JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> @since 2.7
*/
Class<?> keyClass = findSerializationKeyType(a, keyType);
if (keyClass != null) {
if (keyType.hasRawClass(keyClass)) {
keyType = keyType.withStaticTyping();
} else {
Class<?> currRaw = keyType.getRawClass();
try {
// 19-May-2016, tatu: As per [databind#1231], [databind#1178] may need to actually
// specialize (narrow) type sometimes, even if more commonly opposite
// is needed.
if (keyClass.isAssignableFrom(currRaw)) { // common case
keyType = tf.constructGeneralizedType(keyType, keyClass);
} else if (currRaw.isAssignableFrom(keyClass)) { // specialization, ok as well
keyType = tf.constructSpecializedType(keyType, keyClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization key type %s into %s; types not related",
keyType, keyClass.getName()));
}
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen key type of %s with concrete-type annotation (value %s), from '%s': %s",
type, keyClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
type = ((MapLikeType) type).withKeyType(keyType);
}
}
JavaType contentType = type.getContentType();
if (contentType != null) { // collection[like], map[like], array, reference
// And then value types for all containers:
Class<?> contentClass = findSerializationContentType(a, contentType);
if (contentClass != null) {
if (contentType.hasRawClass(contentClass)) {
contentType = contentType.withStaticTyping();
} else {
// 03-Apr-2016, tatu: As per [databind#1178], may need to actually
// specialize (narrow) type sometimes, even if more commonly opposite
// is needed.
Class<?> currRaw = contentType.getRawClass();
try {
if (contentClass.isAssignableFrom(currRaw)) { // common case
contentType = tf.constructGeneralizedType(contentType, contentClass);
} else if (currRaw.isAssignableFrom(contentClass)) { // specialization, ok as well
contentType = tf.constructSpecializedType(contentType, contentClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization content type %s into %s;
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> * @since 2.7
*/
public JavaType refineDeserializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> valueClass = findDeserializationType(a, type);
if ((valueClass != null) && !type.hasRawClass(valueClass)) {
try {
type = tf.constructSpecializedType(type, valueClass);
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to narrow type %s with annotation (value %s), from '%s': %s",
type, valueClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
Class<?> keyClass = findDeserializationKeyType(a, keyType);
if (keyClass != null) {
try {
keyType = tf.constructSpecializedType(keyType, keyClass);
type = ((MapLikeType) type).withKeyType(keyType);
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to narrow key type of %s with concrete-type annotation (value %s), from '%s': %s",
type, keyClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
JavaType contentType = type.getContentType();
if (contentType != null) { // collection[like], map[like], array, reference
// And then value types for all containers:
Class<?> contentClass = findDeserializationContentType(a, contentType);
if (contentClass != null) {
try {
contentType = tf.constructSpecializedType(contentType, contentClass);
type = type.withContentType(contentType);
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to narrow value type of %s with concrete-type annotation (value %s), from '%s': %s",
type,
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> to combine polymorphic types, Converters, but the least sucky way
* is probably to use Converter and ignore polymorphic type. Alternative
* would be to try to change `TypeDeserializer` to accept `Converter` to
* invoke... but that is more intrusive, yet not guaranteeing success.
*/
// method called up to 2.7.3:
// Object delegateValue = _delegateDeserializer.deserializeWithType(p, ctxt, typeDeserializer);
// method called since 2.7.4
Object delegateValue = _delegateDeserializer.deserialize(p, ctxt);
if (delegateValue == null) {
return null;
}
return convertValue(delegateValue);
}
@SuppressWarnings("unchecked")
@Override
public T deserialize(JsonParser p, DeserializationContext ctxt, Object intoValue)
throws IOException
{
if (_delegateType.getRawClass().isAssignableFrom(intoValue.getClass())){
return (T) _delegateDeserializer.deserialize(p, ctxt, intoValue);
}
return (T) _handleIncompatibleUpdateValue(p, ctxt, intoValue);
}
/**
* Overridable handler method called when {@link #deserialize(JsonParser, DeserializationContext, Object)}
* has been called with a value that is not compatible with delegate value.
* Since no conversion are expected for such "updateValue" case, this is normally not
* an operation that can be permitted, and the default behavior is to throw exception.
* Sub-classes may choose to try alternative approach if they have more information on
* exact usage and constraints.
*
* @since 2.6
*/
protected Object _handleIncompatibleUpdateValue(JsonParser p, DeserializationContext ctxt, Object intoValue)
throws IOException
{
throw new UnsupportedOperationException(String.format
("Can not update object of type %s (using deserializer for type %s)"
+intoValue.getClass().getName(), _delegateType));
}
/*
/**********************************************************
/* Overridable methods
/**********************************************************
*/
/**
* Method called to convert from "delegate value" (which was deserialized
* from JSON using standard Jackson deserializer for delegate type)
* into desired target type.
*<P>
* The default implementation uses configured {@link Converter} to do
* conversion.
*
* @param delegateValue
*
* @return Result of conversion
*/
protected T convertValue(Object delegateValue) {
return _converter.convert(delegateValue);
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> }
break;
case NON_ABSENT: // new with 2.6, to support Guava/JDK8 Optionals
// always suppress nulls
suppressNulls = true;
// and for referential types, also "empty", which in their case means "absent"
if (declaredType.isReferenceType()) {
valueToSuppress = BeanPropertyWriter.MARKER_FOR_EMPTY;
}
break;
case NON_EMPTY:
// always suppress nulls
suppressNulls = true;
// but possibly also 'empty' values:
valueToSuppress = BeanPropertyWriter.MARKER_FOR_EMPTY;
break;
case NON_NULL:
suppressNulls = true;
// fall through
case ALWAYS: // default
default:
// we may still want to suppress empty collections, as per [JACKSON-254]:
if (declaredType.isContainerType()
&& !_config.isEnabled(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS)) {
valueToSuppress = BeanPropertyWriter.MARKER_FOR_EMPTY;
}
break;
}
BeanPropertyWriter bpw = new BeanPropertyWriter(propDef,
am, _beanDesc.getClassAnnotations(), declaredType,
ser, typeSer, serializationType, suppressNulls, valueToSuppress);
// How about custom null serializer?
Object serDef = _annotationIntrospector.findNullSerializer(am);
if (serDef != null) {
bpw.assignNullSerializer(prov.serializerInstance(am, serDef));
}
// And then, handling of unwrapping
NameTransformer unwrapper = _annotationIntrospector.findUnwrappingNameTransformer(am);
if (unwrapper != null) {
bpw = bpw.unwrappingWriter(unwrapper);
}
return bpw;
}
/*
/**********************************************************
/* Helper methods; annotation access
/**********************************************************
*/
/**
* Method that will try to determine statically defined type of property
* being serialized, based on annotations (for overrides), and alternatively
* declared type (if static typing for serialization is enabled).
* If neither can be used (no annotations, dynamic typing), returns null.
*/
protected JavaType findSerializationType(Annotated a, boolean useStaticTyping, JavaType declaredType)
throws JsonMappingException
{
JavaType secondary = _annotationIntrospector.refineSerializationType(_config, a, declaredType);
// 11-Oct-2015, tatu: As of 2.7, not 100% sure following checks are needed. But keeping
// for now, just in case
if (secondary != declaredType) {
Class<?> serClass = secondary.getRaw
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>Class();
// Must be a super type to be usable
Class<?> rawDeclared = declaredType.getRawClass();
if (serClass.isAssignableFrom(rawDeclared)) {
; // fine as is
} else {
/* 18-Nov-2010, tatu: Related to fixing [JACKSON-416], an issue with such
* check is that for deserialization more specific type makes sense;
* and for serialization more generic. But alas JAXB uses but a single
* annotation to do both... Hence, we must just discard type, as long as
* types are related
*/
if (!rawDeclared.isAssignableFrom(serClass)) {
throw new IllegalArgumentException("Illegal concrete-type annotation for method '"+a.getName()+"': class "+serClass.getName()+" not a super-type of (declared) class "+rawDeclared.getName());
}
/* 03-Dec-2010, tatu: Actually, ugh, we may need to further relax this
* and actually accept subtypes too for serialization. Bit dangerous in theory
* but need to trust user here...
*/
}
useStaticTyping = true;
declaredType = secondary;
}
// If using static typing, declared type is known to be the type...
JsonSerialize.Typing typing = _annotationIntrospector.findSerializationTyping(a);
if ((typing != null) && (typing != JsonSerialize.Typing.DEFAULT_TYPING)) {
useStaticTyping = (typing == JsonSerialize.Typing.STATIC);
}
if (useStaticTyping) {
// 11-Oct-2015, tatu: Make sure JavaType also "knows" static-ness...
return declaredType.withStaticTyping();
}
return null;
}
/*
/**********************************************************
/* Helper methods for default value handling
/**********************************************************
*/
protected Object getDefaultBean()
{
Object def = _defaultBean;
if (def == null) {
/* If we can fix access rights, we should; otherwise non-public
* classes or default constructor will prevent instantiation
*/
def = _beanDesc.instantiateBean(_config.canOverrideAccessModifiers());
if (def == null) {
// 06-Nov-2015, tatu: As per [databind#998], do not fail.
/*
Class<?> cls = _beanDesc.getClassInfo().getAnnotated();
throw new IllegalArgumentException("Class "+cls.getName()+" has no default constructor; can not instantiate default bean value to support 'properties=JsonSerialize.Inclusion.NON_DEFAULT' annotation");
*/
// And use a marker
def = NO_DEFAULT_MARKER;
}
_defaultBean
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> = def;
}
return (def == NO_DEFAULT_MARKER) ? null : _defaultBean;
}
/**
* Accessor used to find out "default value" for given property, to use for
* comparing values to serialize, to determine whether to exclude value from serialization with
* inclusion type of {@link com.fasterxml.jackson.annotation.JsonInclude.Include#NON_EMPTY}.
* This method is called when we specifically want to know default value within context
* of a POJO, when annotation is within containing class, and not for property or
* defined as global baseline.
*<p>
* Note that returning of pseudo-type
*
* @since 2.7
*/
protected Object getPropertyDefaultValue(String name, AnnotatedMember member,
JavaType type)
{
Object defaultBean = getDefaultBean();
if (defaultBean == null) {
return getDefaultValue(type);
}
try {
return member.getValue(defaultBean);
} catch (Exception e) {
return _throwWrapped(e, name, defaultBean);
}
}
/**
* Accessor used to find out "default value" to use for comparing values to
* serialize, to determine whether to exclude value from serialization with
* inclusion type of {@link com.fasterxml.jackson.annotation.JsonInclude.Include#NON_DEFAULT}.
*<p>
* Default logic is such that for primitives and wrapper types for primitives, expected
* defaults (0 for `int` and `java.lang.Integer`) are returned; for Strings, empty String,
* and for structured (Maps, Collections, arrays) and reference types, criteria
* {@link com.fasterxml.jackson.annotation.JsonInclude.Include#NON_DEFAULT}
* is used.
*
* @since 2.7
*/
protected Object getDefaultValue(JavaType type)
{
// 06-Nov-2015, tatu: Returning null is fine for Object types; but need special
// handling for primitives since they are never passed as nulls.
Class<?> cls = type.getRawClass();
Class<?> prim = ClassUtil.primitiveType(cls);
if (prim != null) {
return ClassUtil.defaultValue(prim);
}
if (type.isContainerType() || type.isReferenceType()) {
return JsonInclude.Include.NON_EMPTY;
}
if (cls == String.class) {
return "";
}
return null;
}
/*
/**********************************************************
/* Helper methods for exception handling
/**********************************************************
*/
protected Object _throwWrapped(Exception e, String propName, Object defaultBean)
{
Throwable t = e;
while (t.getCause() != null)
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>015, tatu: As per [databind#749], we can not statically determine
* between name() and toString(), need to construct `EnumValues` with names,
* handle toString() case dynamically (for example)
*/
EnumValues v = EnumValues.constructFromName(config, (Class<Enum<?>>) enumClass);
Boolean serializeAsIndex = _isShapeWrittenUsingIndex(enumClass, format, true);
return new EnumSerializer(v, serializeAsIndex);
}
/**
* To support some level of per-property configuration, we will need
* to make things contextual. We are limited to "textual vs index"
* choice here, however.
*/
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException
{
if (property != null) {
JsonFormat.Value format = prov.getAnnotationIntrospector().findFormat((Annotated) property.getMember());
if (format != null) {
Boolean serializeAsIndex = _isShapeWrittenUsingIndex(property.getType().getRawClass(), format, false);
if (serializeAsIndex != _serializeAsIndex) {
return new EnumSerializer(_values, serializeAsIndex);
}
}
}
return this;
}
/*
/**********************************************************
/* Extended API for Jackson databind core
/**********************************************************
*/
public EnumValues getEnumValues() { return _values; }
/*
/**********************************************************
/* Actual serialization
/**********************************************************
*/
@Override
public final void serialize(Enum<?> en, JsonGenerator gen, SerializerProvider serializers)
throws IOException
{
// [JACKSON-684]: serialize as index?
if (_serializeAsIndex(serializers)) {
gen.writeNumber(en.ordinal());
return;
}
// [databind#749]: or via toString()?
if (serializers.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)) {
gen.writeString(en.toString());
return;
}
gen.writeString(_values.serializedValueFor(en));
}
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
{
// [JACKSON-684]: serialize as index?
if (_serializeAsIndex(provider)) {
return createSchemaNode("integer", true);
}
ObjectNode objectNode = createSchemaNode("string", true);
if (typeHint != null) {
JavaType type = provider.constructType(typeHint);
if (type.isEnumType()) {
ArrayNode enumNode = objectNode.putArray("enum");
for (SerializableString value : _values.values()) {
enumNode.add(
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
if (!JsonDeserializer.class.isAssignableFrom(deserClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "+deserClass.getName()+"; expected Class<JsonDeserializer>");
}
HandlerInstantiator hi = _config.getHandlerInstantiator();
deser = (hi == null) ? null : hi.deserializerInstance(_config, ann, deserClass);
if (deser == null) {
deser = (JsonDeserializer<?>) ClassUtil.createInstance(deserClass,
_config.canOverrideAccessModifiers());
}
}
// First: need to resolve
if (deser instanceof ResolvableDeserializer) {
((ResolvableDeserializer) deser).resolve(this);
}
return (JsonDeserializer<Object>) deser;
}
@Override
public final KeyDeserializer keyDeserializerInstance(Annotated ann, Object deserDef)
throws JsonMappingException
{
if (deserDef == null) {
return null;
}
KeyDeserializer deser;
if (deserDef instanceof KeyDeserializer) {
deser = (KeyDeserializer) deserDef;
} else {
if (!(deserDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned key deserializer definition of type "
+deserDef.getClass().getName()
+"; expected type KeyDeserializer or Class<KeyDeserializer> instead");
}
Class<?> deserClass = (Class<?>)deserDef;
// there are some known "no class" markers to consider too:
if (deserClass == KeyDeserializer.None.class || ClassUtil.isBogusClass(deserClass)) {
return null;
}
if (!KeyDeserializer.class.isAssignableFrom(deserClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "+deserClass.getName()
+"; expected Class<KeyDeserializer>");
}
HandlerInstantiator hi = _config.getHandlerInstantiator();
deser = (hi == null) ? null : hi.keyDeserializerInstance(_config, ann, deserClass);
if (deser == null) {
deser = (KeyDeserializer) ClassUtil.createInstance(deserClass,
_config.canOverrideAccessModifiers());
}
}
// First: need to resolve
if (deser instanceof ResolvableDeserializer) {
((ResolvableDeserializer) deser).resolve(this);
}
return deser;
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
/**
* Fluent factory method used for constructing a blueprint instance
* with different factory
*/
public abstract DefaultDeserializationContext with(DeserializerFactory factory);
/**
* Method called to create actual usable per-deserialization
* context instance.
*/
public abstract DefaultDeserializationContext createInstance(
DeserializationConfig config, JsonParser
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> findPropertyInclusion(JsonInclude.Value defValue) {
if (_annotationIntrospector != null) {
JsonInclude.Value incl = _annotationIntrospector.findPropertyInclusion(_classInfo);
if (incl != null) {
return defValue.withOverrides(incl);
}
}
return defValue;
}
/**
* Method used to locate the method of introspected class that
* implements {@link com.fasterxml.jackson.annotation.JsonAnyGetter}.
* If no such method exists null is returned.
* If more than one are found, an exception is thrown.
*/
@Override
public AnnotatedMember findAnyGetter() throws IllegalArgumentException
{
AnnotatedMember anyGetter = (_propCollector == null) ? null
: _propCollector.getAnyGetter();
if (anyGetter != null) {
/* For now let's require a Map; in future can add support for other
* types like perhaps Iterable<Map.Entry>?
*/
Class<?> type = anyGetter.getRawType();
if (!Map.class.isAssignableFrom(type)) {
throw new IllegalArgumentException("Invalid 'any-getter' annotation on method "+anyGetter.getName()+"(): return type is not instance of java.util.Map");
}
}
return anyGetter;
}
@Override
public Map<String,AnnotatedMember> findBackReferenceProperties()
{
HashMap<String,AnnotatedMember> result = null;
// boolean hasIgnored = (_ignoredPropertyNames != null);
for (BeanPropertyDefinition property : _properties()) {
/* 23-Sep-2014, tatu: As per [Databind#426], we _should_ try to avoid
* calling accessor, as it triggers exception from seeming conflict.
* But the problem is that _ignoredPropertyNames here only contains
* ones ignored on per-property annotations, but NOT class annotations...
* so commented out part does not work, alas
*/
/*
if (hasIgnored && _ignoredPropertyNames.contains(property.getName())) {
continue;
}
*/
AnnotatedMember am = property.getMutator();
if (am == null) {
continue;
}
AnnotationIntrospector.ReferenceProperty refDef = _annotationIntrospector.findReferenceType(am);
if (refDef != null && refDef.isBackReference()) {
if (result == null) {
result = new HashMap<String,AnnotatedMember>();
}
String refName = refDef.getName();
if (result.put(refName, am) != null) {
throw new IllegalArgumentException("Multiple back-reference properties with name '"+refName+"'");
}
}
}
return result;
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
}
/*
/**********************************************************
/* Introspection for deserialization, factories
/**********************************************************
*/
@Override
public List<AnnotatedMethod> getFactoryMethods()
{
// must filter out anything that clearly is not a factory method
List<AnnotatedMethod> candidates = _classInfo.getStaticMethods();
if (candidates.isEmpty()) {
return candidates;
}
ArrayList<AnnotatedMethod> result = new ArrayList<AnnotatedMethod>();
for (AnnotatedMethod am : candidates) {
if (isFactoryMethod(am)) {
result.add(am);
}
}
return result;
}
@Override
public Constructor<?> findSingleArgConstructor(Class<?>... argTypes)
{
for (AnnotatedConstructor ac : _classInfo.getConstructors()) {
// This list is already filtered to only include accessible
/* (note: for now this is a redundant check; but in future
* that may change; thus leaving here for now)
*/
if (ac.getParameterCount() == 1) {
Class<?> actArg = ac.getRawParameterType(0);
for (Class<?> expArg : argTypes) {
if (expArg == actArg) {
return ac.getAnnotated();
}
}
}
}
return null;
}
@Override
public Method findFactoryMethod(Class<?>... expArgTypes)
{
// So, of all single-arg static methods:
for (AnnotatedMethod am : _classInfo.getStaticMethods()) {
if (isFactoryMethod(am)) {
// And must take one of expected arg types (or supertype)
Class<?> actualArgType = am.getRawParameterType(0);
for (Class<?> expArgType : expArgTypes) {
// And one that matches what we would pass in
if (actualArgType.isAssignableFrom(expArgType)) {
return am.getAnnotated();
}
}
}
}
return null;
}
protected boolean isFactoryMethod(AnnotatedMethod am)
{
/* First: return type must be compatible with the introspected class
* (i.e. allowed to be sub-class, although usually is the same
* class)
*/
Class<?> rt = am.getRawReturnType();
if (!getBeanClass().isAssignableFrom(rt)) {
return false;
}
/* Also: must be a recognized factory method, meaning:
* (a) marked with @JsonCreator annotation, or
* (b) "valueOf" (at this point, need not be public)
*/
if (_annotationIntrospector.hasCreatorAnnotation(am)) {
return true;
}
final String name = am.getName();
if ("valueOf".equals(name)) {
return true;
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> // [Issue#208] Also accept "fromString()", if takes String or CharSequence
if ("fromString".equals(name)) {
if (1 == am.getParameterCount()) {
Class<?> cls = am.getRawParameterType(0);
if (cls == String.class || CharSequence.class.isAssignableFrom(cls)) {
return true;
}
}
}
return false;
}
/**
* @deprecated Since 2.4, use <code>findCreatorParameterNames()</code> instead.
*/
@Deprecated
public List<String> findCreatorPropertyNames()
{
List<PropertyName> params = findCreatorParameterNames();
if (params.isEmpty()) {
return Collections.emptyList();
}
List<String> result = new ArrayList<String>(params.size());
for (PropertyName name : params) {
result.add(name.getSimpleName());
}
return result;
}
/**
* @deprecated Since 2.5, does not seem to be used at all.
*/
@Deprecated
public List<PropertyName> findCreatorParameterNames()
{
for (int i = 0; i < 2; ++i) {
List<? extends AnnotatedWithParams> l = (i == 0)
? getConstructors() : getFactoryMethods();
for (AnnotatedWithParams creator : l) {
int argCount = creator.getParameterCount();
if (argCount < 1) continue;
PropertyName name = _findCreatorPropertyName(creator.getParameter(0));
if (name == null || name.isEmpty()) {
continue;
}
List<PropertyName> names = new ArrayList<PropertyName>();
names.add(name);
for (int p = 1; p < argCount; ++p) {
name = _findCreatorPropertyName(creator.getParameter(p));
names.add(name);
}
return names;
}
}
return Collections.emptyList();
}
protected PropertyName _findCreatorPropertyName(AnnotatedParameter param)
{
PropertyName name = _annotationIntrospector.findNameForDeserialization(param);
if (name == null || name.isEmpty()) {
String str = _annotationIntrospector.findImplicitPropertyName(param);
if (str != null && !str.isEmpty()) {
name = PropertyName.construct(str);
}
}
return name;
}
/*
/**********************************************************
/* Introspection for deserialization, other
/**********************************************************
*/
@Override
public Class<?> findPOJOBuilder() {
return (_annotationIntrospector == null) ?
null : _annotationIntrospector.findPOJOBuilder(_classInfo);
}
@Override
public JsonPOJOBuilder.Value findPO
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>JOBuilderConfig()
{
return (_annotationIntrospector == null) ?
null : _annotationIntrospector.findPOJOBuilderConfig(_classInfo);
}
@Override
public Converter<Object,Object> findDeserializationConverter()
{
if (_annotationIntrospector == null) {
return null;
}
return _createConverter(_annotationIntrospector.findDeserializationConverter(_classInfo));
}
@Override
public String findClassDescription() {
return (_annotationIntrospector == null) ?
null : _annotationIntrospector.findClassDescription(_classInfo);
}
/*
/**********************************************************
/* Helper methods for field introspection
/**********************************************************
*/
/**
* @param ignoredProperties (optional) names of properties to ignore;
* any fields that would be recognized as one of these properties
* is ignored.
* @param forSerialization If true, will collect serializable property
* fields; if false, deserializable
*
* @return Ordered Map with logical property name as key, and
* matching field as value.
*
* @deprecated Since 2.7.2, does not seem to be used?
*/
@Deprecated
public LinkedHashMap<String,AnnotatedField> _findPropertyFields(
Collection<String> ignoredProperties, boolean forSerialization)
{
LinkedHashMap<String,AnnotatedField> results = new LinkedHashMap<String,AnnotatedField>();
for (BeanPropertyDefinition property : _properties()) {
AnnotatedField f = property.getField();
if (f != null) {
String name = property.getName();
if (ignoredProperties != null) {
if (ignoredProperties.contains(name)) {
continue;
}
}
results.put(name, f);
}
}
return results;
}
/*
/**********************************************************
/* Helper methods, other
/**********************************************************
*/
@SuppressWarnings("unchecked")
public Converter<Object,Object> _createConverter(Object converterDef)
{
if (converterDef == null) {
return null;
}
if (converterDef instanceof Converter<?,?>) {
return (Converter<Object,Object>) converterDef;
}
if (!(converterDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned Converter definition of type "
+converterDef.getClass().getName()+"; expected type Converter or Class<Converter> instead");
}
Class<?> converterClass = (Class<?>)converterDef;
// there are some known "no class" markers to consider too:
if (converterClass == Converter.None.class || ClassUtil.isBogusClass(converterClass)) {
return null;
}
if (!Converter.class.isAssignableFrom(converterClass)) {
throw new IllegalStateException("
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
/**
* Deserializer for {@link EnumMap} values.
* <p>
* Note: casting within this class is all messed up -- just could not figure out a way
* to properly deal with recursive definition of "EnumMap<K extends Enum<K>, V>
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public class EnumMapDeserializer
extends ContainerDeserializerBase<EnumMap<?,?>>
implements ContextualDeserializer
{
private static final long serialVersionUID = 1;
protected final JavaType _mapType;
protected final Class<?> _enumClass;
protected KeyDeserializer _keyDeserializer;
protected JsonDeserializer<Object> _valueDeserializer;
/**
* If value instances have polymorphic type information, this
* is the type deserializer that can handle it
*/
protected final TypeDeserializer _valueTypeDeserializer;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public EnumMapDeserializer(JavaType mapType, KeyDeserializer keyDeserializer, JsonDeserializer<?> valueDeser, TypeDeserializer valueTypeDeser)
{
super(mapType);
_mapType = mapType;
_enumClass = mapType.getKeyType().getRawClass();
_keyDeserializer = keyDeserializer;
_valueDeserializer = (JsonDeserializer<Object>) valueDeser;
_valueTypeDeserializer = valueTypeDeser;
}
public EnumMapDeserializer withResolved(KeyDeserializer keyDeserializer, JsonDeserializer<?> valueDeserializer, TypeDeserializer valueTypeDeser)
{
if ((keyDeserializer == _keyDeserializer) && (valueDeserializer == _valueDeserializer) && (valueTypeDeser == _valueTypeDeserializer)) {
return this;
}
return new EnumMapDeserializer(_mapType, keyDeserializer, valueDeserializer, _valueTypeDeserializer);
}
/**
* Method called to finalize setup of this deserializer,
* when it is known for which property deserializer is needed for.
*/
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException
{
// note: instead of finding key deserializer, with enums we actually
// work with regular deserializers (less code duplication; but not
// quite as clean as it ought to be)
KeyDeserializer kd = _keyDeserializer;
if (kd == null) {
kd = ctxt.findKeyDeserializer(_mapType.getKeyType
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>(type, endBefore, result, addClassItself);
return result;
}
/**
* @since 2.7
*/
public static List<Class<?>> findRawSuperTypes(Class<?> cls, Class<?> endBefore, boolean addClassItself) {
if ((cls == null) || (cls == endBefore) || (cls == Object.class)) {
return Collections.emptyList();
}
List<Class<?>> result = new ArrayList<Class<?>>(8);
_addRawSuperTypes(cls, endBefore, result, addClassItself);
return result;
}
/**
* Method for finding all super classes (but not super interfaces) of given class,
* starting with the immediate super class and ending in the most distant one.
* Class itself is included if <code>addClassItself</code> is true.
*
* @since 2.7
*/
public static List<Class<?>> findSuperClasses(Class<?> cls, Class<?> endBefore,
boolean addClassItself) {
List<Class<?>> result = new LinkedList<Class<?>>();
if ((cls != null) && (cls != endBefore)) {
if (addClassItself) {
result.add(cls);
}
while ((cls = cls.getSuperclass()) != null) {
if (cls == endBefore) {
break;
}
result.add(cls);
}
}
return result;
}
@Deprecated // since 2.7
public static List<Class<?>> findSuperTypes(Class<?> cls, Class<?> endBefore) {
return findSuperTypes(cls, endBefore, new ArrayList<Class<?>>(8));
}
@Deprecated // since 2.7
public static List<Class<?>> findSuperTypes(Class<?> cls, Class<?> endBefore, List<Class<?>> result) {
_addRawSuperTypes(cls, endBefore, result, false);
return result;
}
private static void _addSuperTypes(JavaType type, Class<?> endBefore, Collection<JavaType> result,
boolean addClassItself)
{
if (type == null) {
return;
}
final Class<?> cls = type.getRawClass();
if (cls == endBefore || cls == Object.class) { return; }
if (addClassItself) {
if (result.contains(type)) { // already added, no need to check supers
return;
}
result.add(type);
}
for (JavaType intCls : type.getInterfaces()) {
_addSuperTypes(intCls, endBefore, result, true);
}
_addSuperTypes(type.getSuperClass(), endBefore, result, true);
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> locals, anonymous, are not good:
if (hasEnclosingMethod(type)) {
return null;
}
if (!Modifier.isStatic(type.getModifiers())) {
return getEnclosingClass(type);
}
} catch (SecurityException e) { }
return null;
}
/**
* Helper method used to weed out dynamic Proxy types; types that do
* not expose concrete method API that we could use to figure out
* automatic Bean (property) based serialization.
*/
public static boolean isProxyType(Class<?> type)
{
// As per [databind#57], should NOT disqualify JDK proxy:
/*
// Then: well-known proxy (etc) classes
if (Proxy.isProxyClass(type)) {
return true;
}
*/
String name = type.getName();
// Hibernate uses proxies heavily as well:
if (name.startsWith("net.sf.cglib.proxy.")
|| name.startsWith("org.hibernate.proxy.")) {
return true;
}
// Not one of known proxies, nope:
return false;
}
/**
* Helper method that checks if given class is a concrete one;
* that is, not an interface or abstract class.
*/
public static boolean isConcrete(Class<?> type)
{
int mod = type.getModifiers();
return (mod & (Modifier.INTERFACE | Modifier.ABSTRACT)) == 0;
}
public static boolean isConcrete(Member member)
{
int mod = member.getModifiers();
return (mod & (Modifier.INTERFACE | Modifier.ABSTRACT)) == 0;
}
public static boolean isCollectionMapOrArray(Class<?> type)
{
if (type.isArray()) return true;
if (Collection.class.isAssignableFrom(type)) return true;
if (Map.class.isAssignableFrom(type)) return true;
return false;
}
/*
/**********************************************************
/* Type name handling methods
/**********************************************************
*/
/**
* Helper method used to construct appropriate description
* when passed either type (Class) or an instance; in latter
* case, class of instance is to be used.
*/
public static String getClassDescription(Object classOrInstance)
{
if (classOrInstance == null) {
return "unknown";
}
Class<?> cls = (classOrInstance instanceof Class<?>) ?
(Class<?>) classOrInstance : classOrInstance.getClass();
return cls.getName();
}
/*
/**********************************************************
/* Class loading
/**********************************************************
*/
/**
* @deprecated Since 2.6, use method in {@link com.fasterxml.jackson.databind.type.TypeFactory}.
*/
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.jsontype.impl;
import java.util.*;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.databind.jsontype.SubtypeResolver;
/**
* Standard {@link SubtypeResolver} implementation.
*/
public class StdSubtypeResolver
extends SubtypeResolver
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
protected LinkedHashSet<NamedType> _registeredSubtypes;
public StdSubtypeResolver() { }
/*
/**********************************************************
/* Subtype registration
/**********************************************************
*/
@Override
public void registerSubtypes(NamedType... types) {
if (_registeredSubtypes == null) {
_registeredSubtypes = new LinkedHashSet<NamedType>();
}
for (NamedType type : types) {
_registeredSubtypes.add(type);
}
}
@Override
public void registerSubtypes(Class<?>... classes) {
NamedType[] types = new NamedType[classes.length];
for (int i = 0, len = classes.length; i < len; ++i) {
types[i] = new NamedType(classes[i]);
}
registerSubtypes(types);
}
/*
/**********************************************************
/* Resolution by class (serialization)
/**********************************************************
*/
@Override
public Collection<NamedType> collectAndResolveSubtypesByClass(MapperConfig<?> config,
AnnotatedMember property, JavaType baseType)
{
final AnnotationIntrospector ai = config.getAnnotationIntrospector();
// for backwards compatibility, must allow null here:
Class<?> rawBase = (baseType == null) ? property.getRawType() : baseType.getRawClass();
HashMap<NamedType, NamedType> collected = new HashMap<NamedType, NamedType>();
// start with registered subtypes (which have precedence)
if (_registeredSubtypes != null) {
for (NamedType subtype : _registeredSubtypes) {
// is it a subtype of root type?
if (rawBase.isAssignableFrom(subtype.getType())) { // yes
AnnotatedClass curr = AnnotatedClass.constructWithoutSuperTypes(subtype.getType(), config);
_collectAndResolve(curr, subtype, config, ai, collected);
}
}
}
// then annotated types for property itself
Collection<NamedType> st = ai.findSubtypes(property);
if (st != null
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>) {
for (NamedType nt : st) {
AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(nt.getType(), config);
_collectAndResolve(ac, nt, config, ai, collected);
}
}
NamedType rootType = new NamedType(rawBase, null);
AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(rawBase, config);
// and finally subtypes via annotations from base type (recursively)
_collectAndResolve(ac, rootType, config, ai, collected);
return new ArrayList<NamedType>(collected.values());
}
@Override
public Collection<NamedType> collectAndResolveSubtypesByClass(MapperConfig<?> config,
AnnotatedClass type)
{
final AnnotationIntrospector ai = config.getAnnotationIntrospector();
HashMap<NamedType, NamedType> subtypes = new HashMap<NamedType, NamedType>();
// [JACKSON-257] then consider registered subtypes (which have precedence over annotations)
if (_registeredSubtypes != null) {
Class<?> rawBase = type.getRawType();
for (NamedType subtype : _registeredSubtypes) {
// is it a subtype of root type?
if (rawBase.isAssignableFrom(subtype.getType())) { // yes
AnnotatedClass curr = AnnotatedClass.constructWithoutSuperTypes(subtype.getType(), config);
_collectAndResolve(curr, subtype, config, ai, subtypes);
}
}
}
// and then check subtypes via annotations from base type (recursively)
NamedType rootType = new NamedType(type.getRawType(), null);
_collectAndResolve(type, rootType, config, ai, subtypes);
return new ArrayList<NamedType>(subtypes.values());
}
/*
/**********************************************************
/* Resolution by class (deserialization)
/**********************************************************
*/
@Override
public Collection<NamedType> collectAndResolveSubtypesByTypeId(MapperConfig<?> config,
AnnotatedMember property, JavaType baseType)
{
final AnnotationIntrospector ai = config.getAnnotationIntrospector();
Class<?> rawBase = (baseType == null) ? property.getRawType() : baseType.getRawClass();
// Need to keep track of classes that have been handled already
Set<Class<?>> typesHandled = new HashSet<Class<?>>();
Map<String,NamedType> byName = new LinkedHashMap<String,NamedType>();
// start with lowest-precedence, which is from type hierarchy
NamedType rootType = new NamedType(rawBase, null);
AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(rawBase, config);
_collectAndResolveByTypeId(ac, rootType
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>, config, typesHandled, byName);
// then with definitions from property
Collection<NamedType> st = ai.findSubtypes(property);
if (st != null) {
for (NamedType nt : st) {
ac = AnnotatedClass.constructWithoutSuperTypes(nt.getType(), config);
_collectAndResolveByTypeId(ac, nt, config, typesHandled, byName);
}
}
// and finally explicit type registrations (highest precedence)
if (_registeredSubtypes != null) {
for (NamedType subtype : _registeredSubtypes) {
// is it a subtype of root type?
if (rawBase.isAssignableFrom(subtype.getType())) { // yes
AnnotatedClass curr = AnnotatedClass.constructWithoutSuperTypes(subtype.getType(), config);
_collectAndResolveByTypeId(curr, subtype, config, typesHandled, byName);
}
}
}
return _combineNamedAndUnnamed(typesHandled, byName);
}
@Override
public Collection<NamedType> collectAndResolveSubtypesByTypeId(MapperConfig<?> config,
AnnotatedClass type)
{
Set<Class<?>> typesHandled = new HashSet<Class<?>>();
Map<String,NamedType> byName = new LinkedHashMap<String,NamedType>();
NamedType rootType = new NamedType(type.getRawType(), null);
_collectAndResolveByTypeId(type, rootType, config, typesHandled, byName);
if (_registeredSubtypes != null) {
Class<?> rawBase = type.getRawType();
for (NamedType subtype : _registeredSubtypes) {
// is it a subtype of root type?
if (rawBase.isAssignableFrom(subtype.getType())) { // yes
AnnotatedClass curr = AnnotatedClass.constructWithoutSuperTypes(subtype.getType(), config);
_collectAndResolveByTypeId(curr, subtype, config, typesHandled, byName);
}
}
}
return _combineNamedAndUnnamed(typesHandled, byName);
}
/*
/**********************************************************
/* Deprecated method overrides
/**********************************************************
*/
@Override
@Deprecated
public Collection<NamedType> collectAndResolveSubtypes(AnnotatedMember property,
MapperConfig<?> config, AnnotationIntrospector ai, JavaType baseType)
{
return collectAndResolveSubtypesByClass(config, property, baseType);
}
@Override
@Deprecated
public Collection<NamedType> collectAndResolveSubtypes(AnnotatedClass type,
MapperConfig<?> config, AnnotationIntrospector ai)
{
return collectAndResolveSubtypesByClass(config, type);
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
/**
* Method called to find subtypes for
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>_ANT"));
}
/*
/**********************************************************
/* Parser/generator construction
/**********************************************************
*/
protected JsonParser createParserUsingReader(String input)
throws IOException, JsonParseException
{
return createParserUsingReader(new JsonFactory(), input);
}
protected JsonParser createParserUsingReader(JsonFactory f, String input)
throws IOException, JsonParseException
{
return f.createParser(new StringReader(input));
}
protected JsonParser createParserUsingStream(String input, String encoding)
throws IOException, JsonParseException
{
return createParserUsingStream(new JsonFactory(), input, encoding);
}
protected JsonParser createParserUsingStream(JsonFactory f,
String input, String encoding)
throws IOException, JsonParseException
{
/* 23-Apr-2008, tatus: UTF-32 is not supported by JDK, have to
* use our own codec too (which is not optimal since there's
* a chance both encoder and decoder might have bugs, but ones
* that cancel each other out or such)
*/
byte[] data;
if (encoding.equalsIgnoreCase("UTF-32")) {
data = encodeInUTF32BE(input);
} else {
data = input.getBytes(encoding);
}
InputStream is = new ByteArrayInputStream(data);
return f.createParser(is);
}
/*
/**********************************************************
/* Additional assertion methods
/**********************************************************
*/
protected void assertToken(JsonToken expToken, JsonToken actToken)
{
if (actToken != expToken) {
fail("Expected token "+expToken+", current token "+actToken);
}
}
protected void assertToken(JsonToken expToken, JsonParser jp)
{
assertToken(expToken, jp.getCurrentToken());
}
protected void assertType(Object ob, Class<?> expType)
{
if (ob == null) {
fail("Expected an object of type "+expType.getName()+", got null");
}
Class<?> cls = ob.getClass();
if (!expType.isAssignableFrom(cls)) {
fail("Expected type "+expType.getName()+", got "+cls.getName());
}
}
protected void assertValidLocation(JsonLocation location) {
assertNotNull("Should have non-null location", location);
assertTrue("Should have positive line number", location.getLineNr() > 0);
}
protected void verifyException(Throwable e, String... matches)
{
String msg = e.getMessage();
String lmsg = (msg == null) ? "" : msg.toLowerCase();
for (String match : matches) {
String lmatch = match.toLowerCase();
if (lmsg.indexOf(lmatch) >=
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> }
// also: verify that type is compatible
JavaType referredType = _beanType;
JavaType backRefType = backProp.getType();
boolean isContainer = prop.getType().isContainerType();
if (!backRefType.getRawClass().isAssignableFrom(referredType.getRawClass())) {
throw new IllegalArgumentException("Can not handle managed/back reference '"+refName+"': back reference type ("
+backRefType.getRawClass().getName()+") not compatible with managed type ("
+referredType.getRawClass().getName()+")");
}
return new ManagedReferenceProperty(prop, refName, backProp,
_classAnnotations, isContainer);
}
/**
* Method that wraps given property with {@link ObjectIdReferenceProperty}
* in case where object id resolution is required.
*/
protected SettableBeanProperty _resolvedObjectIdProperty(DeserializationContext ctxt,
SettableBeanProperty prop)
{
ObjectIdInfo objectIdInfo = prop.getObjectIdInfo();
JsonDeserializer<Object> valueDeser = prop.getValueDeserializer();
ObjectIdReader objectIdReader = valueDeser.getObjectIdReader();
if (objectIdInfo == null && objectIdReader == null) {
return prop;
}
return new ObjectIdReferenceProperty(prop, objectIdInfo);
}
/**
* Helper method called to see if given property might be so-called unwrapped
* property: these require special handling.
*/
protected SettableBeanProperty _resolveUnwrappedProperty(DeserializationContext ctxt,
SettableBeanProperty prop)
{
AnnotatedMember am = prop.getMember();
if (am != null) {
NameTransformer unwrapper = ctxt.getAnnotationIntrospector().findUnwrappingNameTransformer(am);
if (unwrapper != null) {
JsonDeserializer<Object> orig = prop.getValueDeserializer();
JsonDeserializer<Object> unwrapping = orig.unwrappingDeserializer(unwrapper);
if (unwrapping != orig && unwrapping != null) {
// might be cleaner to create new instance; but difficult to do reliably, so:
return prop.withValueDeserializer(unwrapping);
}
}
}
return null;
}
/**
* Helper method that will handle gruesome details of dealing with properties
* that have non-static inner class as value...
*/
protected SettableBeanProperty _resolveInnerClassValuedProperty(DeserializationContext ctxt,
SettableBeanProperty prop)
{
/* Should we encounter a property that has non-static inner-class
* as value, we need to add some more magic to find the "hidden" constructor...
*/
JsonDeserializer<Object> deser = prop.getValueDeserializer();
// ideally wouldn't rely on it being BeanDeserializerBase; but for now it'll have to do
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> if (deser instanceof BeanDeserializerBase) {
BeanDeserializerBase bd = (BeanDeserializerBase) deser;
ValueInstantiator vi = bd.getValueInstantiator();
if (!vi.canCreateUsingDefault()) { // no default constructor
Class<?> valueClass = prop.getType().getRawClass();
Class<?> enclosing = ClassUtil.getOuterClass(valueClass);
// and is inner class of the bean class...
if (enclosing != null && enclosing == _beanType.getRawClass()) {
for (Constructor<?> ctor : valueClass.getConstructors()) {
Class<?>[] paramTypes = ctor.getParameterTypes();
if (paramTypes.length == 1 && paramTypes[0] == enclosing) {
if (ctxt.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(ctor, ctxt.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
}
return new InnerClassProperty(prop, ctor);
}
}
}
}
}
return prop;
}
/*
/**********************************************************
/* Public accessors
/**********************************************************
*/
@Override
public boolean isCachable() { return true; }
@Override
public Class<?> handledType() {
return _beanType.getRawClass();
}
/**
* Overridden to return true for those instances that are
* handling value for which Object Identity handling is enabled
* (either via value type or referring property).
*/
@Override
public ObjectIdReader getObjectIdReader() {
return _objectIdReader;
}
public boolean hasProperty(String propertyName) {
return _beanProperties.find(propertyName) != null;
}
public boolean hasViews() {
return _needViewProcesing;
}
/**
* Accessor for checking number of deserialized properties.
*/
public int getPropertyCount() {
return _beanProperties.size();
}
@Override
public Collection<Object> getKnownPropertyNames() {
ArrayList<Object> names = new ArrayList<Object>();
for (SettableBeanProperty prop : _beanProperties) {
names.add(prop.getName());
}
return names;
}
/**
* @deprecated Since 2.3, use {@link #handledType()} instead
*/
@Deprecated
public final Class<?> getBeanClass() { return _beanType.getRawClass(); }
@Override
public JavaType getValueType() { return _beanType; }
/**
* Accessor for iterating over properties this deserializer uses; with
* the exception that properties passed via Creator methods
* (specifically, "property-based constructor") are not included,
* but can be accessed separate by calling
* {@link #creatorProperties}
*/
public Iterator<Set
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>Exception.wrapWithPath(throwOrReturnThrowable(t, ctxt), bean, fieldName);
}
@Deprecated // since 2.4, not used by core Jackson; only relevant for arrays/Collections
public void wrapAndThrow(Throwable t, Object bean, int index, DeserializationContext ctxt) throws IOException {
// [JACKSON-55] Need to add reference information
throw JsonMappingException.wrapWithPath(throwOrReturnThrowable(t, ctxt), bean, index);
}
private Throwable throwOrReturnThrowable(Throwable t, DeserializationContext ctxt)
throws IOException
{
/* 05-Mar-2009, tatu: But one nasty edge is when we get
* StackOverflow: usually due to infinite loop. But that
* often gets hidden within an InvocationTargetException...
*/
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors to be passed as is
if (t instanceof Error) {
throw (Error) t;
}
boolean wrap = (ctxt == null) || ctxt.isEnabled(DeserializationFeature.WRAP_EXCEPTIONS);
// Ditto for IOExceptions; except we may want to wrap JSON exceptions
if (t instanceof IOException) {
if (!wrap || !(t instanceof JsonProcessingException)) {
throw (IOException) t;
}
} else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
}
return t;
}
protected void wrapInstantiationProblem(Throwable t, DeserializationContext ctxt)
throws IOException
{
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors and "plain" IOExceptions to be passed as is
if (t instanceof Error) {
throw (Error) t;
}
boolean wrap = (ctxt == null) || ctxt.isEnabled(DeserializationFeature.WRAP_EXCEPTIONS);
if (t instanceof IOException) {
// Since we have no more information to add, let's not actually wrap..
throw (IOException) t;
} else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
}
throw ctxt.instantiationException(_beanType.getRawClass(), t);
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> because Android (and presumably GAE) have these classes
private final static Class<?> CLASS_DOM_NODE;
private final static Class<?> CLASS_DOM_DOCUMENT;
static {
Class<?> doc = null, node = null;
try {
node = org.w3c.dom.Node.class;
doc = org.w3c.dom.Document.class;
} catch (Exception e) {
// not optimal but will do
System.err.println("WARNING: could not load DOM Node and/or Document classes");
}
CLASS_DOM_NODE = node;
CLASS_DOM_DOCUMENT = doc;
}
// // But Java7 type(s) may or may not be; dynamic lookup should be fine, still
// // (note: also assume it comes from JDK so that ClassLoader issues with OSGi
// // can, I hope, be avoided?)
private final static Class<?> CLASS_JAVA7_PATH;
static {
Class<?> cls = null;
try {
cls = Class.forName("java.nio.file.Path");
} catch (Exception e) {
// not optimal but will do
System.err.println("WARNING: could not load Java7 Path class");
}
CLASS_JAVA7_PATH = cls;
}
public final static OptionalHandlerFactory instance = new OptionalHandlerFactory();
protected OptionalHandlerFactory() { }
/*
/**********************************************************
/* Public API
/**********************************************************
*/
public JsonSerializer<?> findSerializer(SerializationConfig config, JavaType type,
BeanDescription beanDesc)
{
final Class<?> rawType = type.getRawClass();
if ((CLASS_JAVA7_PATH != null) && CLASS_JAVA7_PATH.isAssignableFrom(rawType)) {
return ToStringSerializer.instance;
}
if ((CLASS_DOM_NODE != null) && CLASS_DOM_NODE.isAssignableFrom(rawType)) {
return (JsonSerializer<?>) instantiate(SERIALIZER_FOR_DOM_NODE);
}
String className = rawType.getName();
String factoryName;
if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML) || hasSuperClassStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) {
factoryName = SERIALIZERS_FOR_JAVAX_XML;
} else {
return null;
}
Object ob = instantiate(factoryName);
if (ob == null) { // could warn, if we had logging system (j.u.l?)
return null;
}
return ((Serializers) ob).findSerializer(config, type, beanDesc);
}
public JsonDeserializer<?> findDeserializer(JavaType type, DeserializationConfig config,
BeanDescription beanDesc)
throws
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> JsonMappingException
{
final Class<?> rawType = type.getRawClass();
if ((CLASS_JAVA7_PATH != null) && CLASS_JAVA7_PATH.isAssignableFrom(rawType)) {
return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_PATH);
}
if ((CLASS_DOM_NODE != null) && CLASS_DOM_NODE.isAssignableFrom(rawType)) {
return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_NODE);
}
if ((CLASS_DOM_DOCUMENT != null) && CLASS_DOM_DOCUMENT.isAssignableFrom(rawType)) {
return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_DOCUMENT);
}
String className = rawType.getName();
String factoryName;
if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML)
|| hasSuperClassStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) {
factoryName = DESERIALIZERS_FOR_JAVAX_XML;
} else {
return null;
}
Object ob = instantiate(factoryName);
if (ob == null) { // could warn, if we had logging system (j.u.l?)
return null;
}
return ((Deserializers) ob).findBeanDeserializer(type, config, beanDesc);
}
/*
/**********************************************************
/* Internal helper methods
/**********************************************************
*/
private Object instantiate(String className)
{
try {
return Class.forName(className).newInstance();
} catch (LinkageError e) { }
// too many different kinds to enumerate here:
catch (Exception e) { }
return null;
}
/**
* Since 2.7 we only need to check for class extension, as all implemented
* types are classes, not interfaces. This has performance implications for
* some cases, as we do not need to go over interfaces implemented, just
* superclasses
*
* @since 2.7
*/
private boolean hasSuperClassStartingWith(Class<?> rawType, String prefix)
{
for (Class<?> supertype = rawType.getSuperclass(); supertype != null; supertype = supertype.getSuperclass()) {
if (supertype == Object.class) {
return false;
}
if (supertype.getName().startsWith(prefix)) {
return true;
}
}
return false;
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>SuppressWarnings("unchecked")
public JsonSerializer<Object> findValueSerializer(JavaType valueType, BeanProperty property)
throws JsonMappingException
{
// (see comments from above method)
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(valueType);
if (ser == null) {
ser = _createAndCacheUntypedSerializer(valueType);
if (ser == null) {
ser = getUnknownTypeSerializer(valueType.getRawClass());
if (CACHE_UNKNOWN_MAPPINGS) {
_serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this);
}
return ser;
}
}
}
return (JsonSerializer<Object>) handleSecondaryContextualization(ser, property);
}
/**
* Method variant used when we do NOT want contextualization to happen; it will need
* to be handled at a later point, but caller wants to be able to do that
* as needed; sometimes to avoid infinite loops
*
* @since 2.5
*/
public JsonSerializer<Object> findValueSerializer(Class<?> valueType) throws JsonMappingException
{
// (see comments from above method)
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(_config.constructType(valueType));
if (ser == null) {
ser = _createAndCacheUntypedSerializer(valueType);
if (ser == null) {
ser = getUnknownTypeSerializer(valueType);
if (CACHE_UNKNOWN_MAPPINGS) {
_serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this);
}
}
}
}
}
return ser;
}
/**
* Method variant used when we do NOT want contextualization to happen; it will need
* to be handled at a later point, but caller wants to be able to do that
* as needed; sometimes to avoid infinite loops
*
* @since 2.5
*/
public JsonSerializer<Object> findValueSerializer(JavaType valueType)
throws JsonMappingException
{
// (see comments from above method)
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(valueType);
if (ser == null) {
ser = _createAndCacheUntypedSerializer(valueType);
if (ser == null) {
ser = getUnknownTypeSerializer(
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>valueType.getRawClass());
if (CACHE_UNKNOWN_MAPPINGS) {
_serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this);
}
}
}
}
return ser;
}
/**
* Similar to {@link #findValueSerializer(JavaType, BeanProperty)}, but used
* when finding "primary" property value serializer (one directly handling
* value of the property). Difference has to do with contextual resolution,
* and method(s) called: this method should only be called when caller is
* certain that this is the primary property value serializer.
*
* @param property Property that is being handled; will never be null, and its
* type has to match <code>valueType</code> parameter.
*
* @since 2.3
*/
@SuppressWarnings("unchecked")
public JsonSerializer<Object> findPrimaryPropertySerializer(JavaType valueType, BeanProperty property)
throws JsonMappingException
{
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(valueType);
if (ser == null) {
ser = _createAndCacheUntypedSerializer(valueType);
if (ser == null) {
ser = getUnknownTypeSerializer(valueType.getRawClass());
// Should this be added to lookups?
if (CACHE_UNKNOWN_MAPPINGS) {
_serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this);
}
return ser;
}
}
}
return (JsonSerializer<Object>) handlePrimaryContextualization(ser, property);
}
/**
* @since 2.3
*/
@SuppressWarnings("unchecked")
public JsonSerializer<Object> findPrimaryPropertySerializer(Class<?> valueType,
BeanProperty property)
throws JsonMappingException
{
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(_config.constructType(valueType));
if (ser == null) {
ser = _createAndCacheUntypedSerializer(valueType);
if (ser == null) {
ser = getUnknownTypeSerializer(valueType);
if (CACHE_UNKNOWN_MAPPINGS) {
_serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this);
}
return ser;
}
}
}
}
return (JsonSerializer<Object>) handlePrimaryContextualization(ser, property);
}
/**
* Method called to locate regular serializer, matching type serializer,
*
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>.isPrimitive()) {
Class<?> wrapperType = ClassUtil.wrapperType(rootType.getRawClass());
// If it's just difference between wrapper, primitive, let it slide
if (wrapperType.isAssignableFrom(value.getClass())) {
return;
}
}
throw JsonMappingException.from(this,
"Incompatible types: declared root type ("+rootType+") vs "
+value.getClass().getName());
}
/**
* Method that will try to find a serializer, either from cache
* or by constructing one; but will not return an "unknown" serializer
* if this can not be done but rather returns null.
*
* @return Serializer if one can be found, null if not.
*/
protected JsonSerializer<Object> _findExplicitUntypedSerializer(Class<?> runtimeType)
throws JsonMappingException
{
// Fast lookup from local lookup thingy works?
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(runtimeType);
if (ser == null) {
// If not, maybe shared map already has it?
ser = _serializerCache.untypedValueSerializer(runtimeType);
if (ser == null) {
ser = _createAndCacheUntypedSerializer(runtimeType);
}
}
/* 18-Sep-2014, tatu: This is unfortunate patch over related change
* that pushes creation of "unknown type" serializer deeper down
* in BeanSerializerFactory; as a result, we need to "undo" creation
* here.
*/
if (isUnknownTypeSerializer(ser)) {
return null;
}
return ser;
}
/*
/**********************************************************
/* Low-level methods for actually constructing and initializing
/* serializers
/**********************************************************
*/
/**
* Method that will try to construct a value serializer; and if
* one is successfully created, cache it for reuse.
*/
protected JsonSerializer<Object> _createAndCacheUntypedSerializer(Class<?> rawType)
throws JsonMappingException
{
JavaType fullType = _config.constructType(rawType);
JsonSerializer<Object> ser;
try {
ser = _createUntypedSerializer(fullType);
} catch (IllegalArgumentException iae) {
/* We better only expose checked exceptions, since those
* are what caller is expected to handle
*/
throw JsonMappingException.from(this, iae.getMessage(), iae);
}
if (ser != null) {
// 21-Dec-2015, tatu: Best to cache for both raw and full-type key
_serializerCache.addAndResolveNonTypedSerializer(rawType, fullType, ser, this);
}
return ser;
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> method used to create a copy with slightly
* different settings. When sub-classing, MUST be overridden.
*/
@SuppressWarnings("unchecked")
protected MapDeserializer withResolved(KeyDeserializer keyDeser,
TypeDeserializer valueTypeDeser, JsonDeserializer<?> valueDeser,
HashSet<String> ignorable)
{
if ((_keyDeserializer == keyDeser) && (_valueDeserializer == valueDeser)
&& (_valueTypeDeserializer == valueTypeDeser) && (_ignorableProperties == ignorable)) {
return this;
}
return new MapDeserializer(this,
keyDeser, (JsonDeserializer<Object>) valueDeser, valueTypeDeser, ignorable);
}
/**
* Helper method used to check whether we can just use the default key
* deserialization, where JSON String becomes Java String.
*/
protected final boolean _isStdKeyDeser(JavaType mapType, KeyDeserializer keyDeser)
{
if (keyDeser == null) {
return true;
}
JavaType keyType = mapType.getKeyType();
if (keyType == null) { // assumed to be Object
return true;
}
Class<?> rawKeyType = keyType.getRawClass();
return ((rawKeyType == String.class || rawKeyType == Object.class)
&& isDefaultKeyDeserializer(keyDeser));
}
public void setIgnorableProperties(String[] ignorable) {
_ignorableProperties = (ignorable == null || ignorable.length == 0) ?
null : ArrayBuilders.arrayToSet(ignorable);
}
/*
/**********************************************************
/* Validation, post-processing (ResolvableDeserializer)
/**********************************************************
*/
@Override
public void resolve(DeserializationContext ctxt) throws JsonMappingException
{
// May need to resolve types for delegate- and/or property-based creators:
if (_valueInstantiator.canCreateUsingDelegate()) {
JavaType delegateType = _valueInstantiator.getDelegateType(ctxt.getConfig());
if (delegateType == null) {
throw new IllegalArgumentException("Invalid delegate-creator definition for "+_mapType
+": value instantiator ("+_valueInstantiator.getClass().getName()
+") returned true for 'canCreateUsingDelegate()', but null for 'getDelegateType()'");
}
/* Theoretically should be able to get CreatorProperty for delegate
* parameter to pass; but things get tricky because DelegateCreator
* may contain injectable values. So, for now, let's pass nothing.
*/
_delegateDeserializer = findDeserializer(ctxt, delegateType, null);
}
if (_valueInstantiator.canCreateFromObjectWith()) {
SettableBeanProperty[] creatorProps = _valueInstantiator.getFromObjectArguments(ctxt.
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>NAME
JsonToken t = p.getCurrentToken();
if (t != JsonToken.START_OBJECT && t != JsonToken.FIELD_NAME) {
throw ctxt.mappingException(getMapClass());
}
if (_standardStringKey) {
_readAndBindStringMap(p, ctxt, result);
return result;
}
_readAndBind(p, ctxt, result);
return result;
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
// In future could check current token... for now this should be enough:
return typeDeserializer.deserializeTypedFromObject(jp, ctxt);
}
/*
/**********************************************************
/* Other public accessors
/**********************************************************
*/
@SuppressWarnings("unchecked")
public final Class<?> getMapClass() { return (Class<Map<Object,Object>>) _mapType.getRawClass(); }
@Override public JavaType getValueType() { return _mapType; }
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
protected final void _readAndBind(JsonParser p, DeserializationContext ctxt,
Map<Object,Object> result) throws IOException
{
final KeyDeserializer keyDes = _keyDeserializer;
final JsonDeserializer<Object> valueDes = _valueDeserializer;
final TypeDeserializer typeDeser = _valueTypeDeserializer;
MapReferringAccumulator referringAccumulator = null;
boolean useObjectId = valueDes.getObjectIdReader() != null;
if (useObjectId) {
referringAccumulator = new MapReferringAccumulator(_mapType.getContentType().getRawClass(), result);
}
String keyStr;
if (p.isExpectedStartObjectToken()) {
keyStr = p.nextFieldName();
} else {
JsonToken t = p.getCurrentToken();
if (t == JsonToken.END_OBJECT) {
return;
}
if (t != JsonToken.FIELD_NAME) {
throw ctxt.mappingException(_mapType.getRawClass(), p.getCurrentToken());
}
keyStr = p.getCurrentName();
}
for (; keyStr != null; keyStr = p.nextFieldName()) {
Object key = keyDes.deserializeKey(keyStr, ctxt);
// And then the value...
JsonToken t = p.nextToken();
if (_ignorableProperties != null && _ignorableProperties.contains(keyStr)) {
p.skipChildren();
continue;
}
try {
// Note: must handle null explicitly here; value deserializers won't
Object value;
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue(ctxt);
} else if (typeDeser ==
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> null) {
value = valueDes.deserialize(p, ctxt);
} else {
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
}
if (useObjectId) {
referringAccumulator.put(key, value);
} else {
result.put(key, value);
}
} catch (UnresolvedForwardReference reference) {
handleUnresolvedReference(p, referringAccumulator, key, reference);
} catch (Exception e) {
wrapAndThrow(e, result, keyStr);
}
}
}
/**
* Optimized method used when keys can be deserialized as plain old
* {@link java.lang.String}s, and there is no custom deserialized
* specified.
*/
protected final void _readAndBindStringMap(JsonParser p, DeserializationContext ctxt,
Map<Object,Object> result) throws IOException
{
final JsonDeserializer<Object> valueDes = _valueDeserializer;
final TypeDeserializer typeDeser = _valueTypeDeserializer;
MapReferringAccumulator referringAccumulator = null;
boolean useObjectId = (valueDes.getObjectIdReader() != null);
if (useObjectId) {
referringAccumulator = new MapReferringAccumulator(_mapType.getContentType().getRawClass(), result);
}
String key;
if (p.isExpectedStartObjectToken()) {
key = p.nextFieldName();
} else {
JsonToken t = p.getCurrentToken();
if (t == JsonToken.END_OBJECT) {
return;
}
if (t != JsonToken.FIELD_NAME) {
throw ctxt.mappingException(_mapType.getRawClass(), p.getCurrentToken());
}
key = p.getCurrentName();
}
for (; key != null; key = p.nextFieldName()) {
JsonToken t = p.nextToken();
if (_ignorableProperties != null && _ignorableProperties.contains(key)) {
p.skipChildren();
continue;
}
try {
// Note: must handle null explicitly here; value deserializers won't
Object value;
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue(ctxt);
} else if (typeDeser == null) {
value = valueDes.deserialize(p, ctxt);
} else {
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
}
if (useObjectId) {
referringAccumulator.put(key, value);
} else {
result.put(key, value);
}
} catch (UnresolvedForwardReference reference) {
handleUnresolvedReference(p, referringAccumulator, key, reference);
} catch (Exception e) {
wrapAndThrow(e, result,
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> key);
}
}
// 23-Mar-2015, tatu: TODO: verify we got END_OBJECT?
}
@SuppressWarnings("unchecked")
public Map<Object,Object> _deserializeUsingCreator(JsonParser p, DeserializationContext ctxt) throws IOException
{
final PropertyBasedCreator creator = _propertyBasedCreator;
// null -> no ObjectIdReader for Maps (yet?)
PropertyValueBuffer buffer = creator.startBuilding(p, ctxt, null);
final JsonDeserializer<Object> valueDes = _valueDeserializer;
final TypeDeserializer typeDeser = _valueTypeDeserializer;
String key;
if (p.isExpectedStartObjectToken()) {
key = p.nextFieldName();
} else if (p.hasToken(JsonToken.FIELD_NAME)) {
key = p.getCurrentName();
} else {
key = null;
}
for (; key != null; key = p.nextFieldName()) {
JsonToken t = p.nextToken(); // to get to value
if (_ignorableProperties != null && _ignorableProperties.contains(key)) {
p.skipChildren(); // and skip it (in case of array/object)
continue;
}
// creator property?
SettableBeanProperty prop = creator.findCreatorProperty(key);
if (prop != null) {
// Last property to set?
if (buffer.assignParameter(prop, prop.deserialize(p, ctxt))) {
p.nextToken();
Map<Object,Object> result;
try {
result = (Map<Object,Object>)creator.build(ctxt, buffer);
} catch (Exception e) {
wrapAndThrow(e, _mapType.getRawClass(), key);
return null;
}
_readAndBind(p, ctxt, result);
return result;
}
continue;
}
// other property? needs buffering
Object actualKey = _keyDeserializer.deserializeKey(key, ctxt);
Object value;
try {
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue(ctxt);
} else if (typeDeser == null) {
value = valueDes.deserialize(p, ctxt);
} else {
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
}
} catch (Exception e) {
wrapAndThrow(e, _mapType.getRawClass(), key);
return null;
}
buffer.bufferMapProperty(actualKey, value);
}
// end of JSON object?
// if so, can just construct and leave...
try {
return (Map<Object,Object>)creator.build(ctxt, buffer);
} catch (Exception e) {
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
wrapAndThrow(e, _mapType.getRawClass(), key);
return null;
}
}
@Deprecated // since 2.5
protected void wrapAndThrow(Throwable t, Object ref) throws IOException {
wrapAndThrow(t, ref, null);
}
private void handleUnresolvedReference(JsonParser jp, MapReferringAccumulator accumulator,
Object key, UnresolvedForwardReference reference)
throws JsonMappingException
{
if (accumulator == null) {
throw JsonMappingException.from(jp, "Unresolved forward reference but no identity info.", reference);
}
Referring referring = accumulator.handleUnresolvedReference(reference, key);
reference.getRoid().appendReferring(referring);
}
private final static class MapReferringAccumulator {
private final Class<?> _valueType;
private Map<Object,Object> _result;
/**
* A list of {@link MapReferring} to maintain ordering.
*/
private List<MapReferring> _accumulator = new ArrayList<MapReferring>();
public MapReferringAccumulator(Class<?> valueType, Map<Object, Object> result) {
_valueType = valueType;
_result = result;
}
public void put(Object key, Object value)
{
if (_accumulator.isEmpty()) {
_result.put(key, value);
} else {
MapReferring ref = _accumulator.get(_accumulator.size() - 1);
ref.next.put(key, value);
}
}
public Referring handleUnresolvedReference(UnresolvedForwardReference reference, Object key)
{
MapReferring id = new MapReferring(this, reference, _valueType, key);
_accumulator.add(id);
return id;
}
public void resolveForwardReference(Object id, Object value) throws IOException
{
Iterator<MapReferring> iterator = _accumulator.iterator();
// Resolve ordering after resolution of an id. This means either:
// 1- adding to the result map in case of the first unresolved id.
// 2- merge the content of the resolved id with its previous unresolved id.
Map<Object,Object> previous = _result;
while (iterator.hasNext()) {
MapReferring ref = iterator.next();
if (ref.hasId(id)) {
iterator.remove();
previous.put(ref.key, value);
previous.putAll(ref.next);
return;
}
previous = ref.next;
}
throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id
+ "] that wasn't previously seen as unresolved.");
}
}
/**
* Helper class to maintain processing order of value.
* The resolved
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>)
{
BasicBeanDescription desc = _findStdTypeDesc(type);
if (desc == null) {
// As per [Databind#550], skip full introspection for some of standard
// structured types as well
desc = _findStdJdkCollectionDesc(cfg, type);
if (desc == null) {
desc = BasicBeanDescription.forDeserialization(
collectProperties(cfg, type, r, false, "set"));
}
}
// should this be cached for FCA?
return desc;
}
@Override
public BasicBeanDescription forClassAnnotations(MapperConfig<?> config,
JavaType type, MixInResolver r)
{
BasicBeanDescription desc = _findStdTypeDesc(type);
if (desc == null) {
desc = _cachedFCA.get(type);
if (desc == null) {
AnnotatedClass ac = AnnotatedClass.construct(type, config, r);
desc = BasicBeanDescription.forOtherUse(config, type, ac);
_cachedFCA.put(type, desc);
}
}
return desc;
}
@Override
public BasicBeanDescription forDirectClassAnnotations(MapperConfig<?> config,
JavaType type, MixInResolver r)
{
BasicBeanDescription desc = _findStdTypeDesc(type);
if (desc == null) {
AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(type.getRawClass(), config, r);
desc = BasicBeanDescription.forOtherUse(config, type, ac);
}
return desc;
}
/*
/**********************************************************
/* Overridable helper methods
/**********************************************************
*/
protected POJOPropertiesCollector collectProperties(MapperConfig<?> config,
JavaType type, MixInResolver r, boolean forSerialization,
String mutatorPrefix)
{
AnnotatedClass ac = AnnotatedClass.construct(type, config, r);
return constructPropertyCollector(config, ac, type, forSerialization, mutatorPrefix);
}
protected POJOPropertiesCollector collectPropertiesWithBuilder(MapperConfig<?> config,
JavaType type, MixInResolver r, boolean forSerialization)
{
boolean useAnnotations = config.isAnnotationProcessingEnabled();
AnnotationIntrospector ai = useAnnotations ? config.getAnnotationIntrospector() : null;
AnnotatedClass ac = AnnotatedClass.construct(type, config, r);
JsonPOJOBuilder.Value builderConfig = (ai == null) ? null : ai.findPOJOBuilderConfig(ac);
String mutatorPrefix = (builderConfig == null) ? "with" : builderConfig.withPrefix;
return constructPropertyCollector(config, ac, type, forSerialization, mutatorPrefix);
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
/**
* Overridable method called for creating {@link POJOPropertiesCollector} instance
* to use; override is needed if a custom sub-class is to be used.
*/
protected POJOPropertiesCollector constructPropertyCollector(MapperConfig<?> config,
AnnotatedClass ac, JavaType type, boolean forSerialization, String mutatorPrefix)
{
return new POJOPropertiesCollector(config, forSerialization, type, ac, mutatorPrefix);
}
/**
* Method called to see if type is one of core JDK types
* that we have cached for efficiency.
*/
protected BasicBeanDescription _findStdTypeDesc(JavaType type)
{
Class<?> cls = type.getRawClass();
if (cls.isPrimitive()) {
if (cls == Boolean.TYPE) {
return BOOLEAN_DESC;
}
if (cls == Integer.TYPE) {
return INT_DESC;
}
if (cls == Long.TYPE) {
return LONG_DESC;
}
} else {
if (cls == String.class) {
return STRING_DESC;
}
}
return null;
}
/**
* Helper method used to decide whether we can omit introspection
* for members (methods, fields, constructors); we may do so for
* a limited number of container types JDK provides.
*/
protected boolean _isStdJDKCollection(JavaType type)
{
if (!type.isContainerType() || type.isArrayType()) {
return false;
}
Class<?> raw = type.getRawClass();
String pkgName = ClassUtil.getPackageName(raw);
if (pkgName != null) {
if (pkgName.startsWith("java.lang")
|| pkgName.startsWith("java.util")) {
/* 23-Sep-2014, tatu: Should we be conservative here (minimal number
* of matches), or ambitious? Let's do latter for now.
*/
if (Collection.class.isAssignableFrom(raw)
|| Map.class.isAssignableFrom(raw)) {
return true;
}
}
}
return false;
}
protected BasicBeanDescription _findStdJdkCollectionDesc(MapperConfig<?> cfg, JavaType type)
{
if (_isStdJDKCollection(type)) {
AnnotatedClass ac = AnnotatedClass.construct(type, cfg);
return BasicBeanDescription.forOtherUse(cfg, type, ac);
}
return null;
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.impl.ObjectIdReader;
import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
/**
* Deserializer only used for abstract types used as placeholders during polymorphic
* type handling deserialization. If so, there is no real deserializer associated
* with nominal type, just {@link TypeDeserializer}; and any calls that do not
* pass such resolver will result in an error.
*/
public class AbstractDeserializer
extends JsonDeserializer<Object>
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
protected final JavaType _baseType;
protected final ObjectIdReader _objectIdReader;
protected final Map<String, SettableBeanProperty> _backRefProperties;
// support for "native" types, which require special care:
protected final boolean _acceptString;
protected final boolean _acceptBoolean;
protected final boolean _acceptInt;
protected final boolean _acceptDouble;
public AbstractDeserializer(BeanDeserializerBuilder builder,
BeanDescription beanDesc, Map<String, SettableBeanProperty> backRefProps)
{
_baseType = beanDesc.getType();
_objectIdReader = builder.getObjectIdReader();
_backRefProperties = backRefProps;
Class<?> cls = _baseType.getRawClass();
_acceptString = cls.isAssignableFrom(String.class);
_acceptBoolean = (cls == Boolean.TYPE) || cls.isAssignableFrom(Boolean.class);
_acceptInt = (cls == Integer.TYPE) || cls.isAssignableFrom(Integer.class);
_acceptDouble = (cls == Double.TYPE) || cls.isAssignableFrom(Double.class);
}
protected AbstractDeserializer(BeanDescription beanDesc)
{
_baseType = beanDesc.getType();
_objectIdReader = null;
_backRefProperties = null;
Class<?> cls = _baseType.getRawClass();
_acceptString = cls.isAssignableFrom(String.class);
_acceptBoolean = (cls == Boolean.TYPE) || cls.isAssignableFrom(Boolean.class);
_acceptInt = (cls == Integer.TYPE) || cls.isAssignableFrom(Integer.class);
_acceptDouble = (cls == Double.TYPE) || cls.isAssignableFrom(Double.class);
}
/**
* Factory method used when constructing instances for non-POJO types, like
* {@link java.util.Map}s.
*
* @since 2.3
*/
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
public static AbstractDeserializer constructForNonPOJO(BeanDescription beanDesc) {
return new AbstractDeserializer(beanDesc);
}
/*
/**********************************************************
/* Public accessors
/**********************************************************
*/
@Override
public Class<?> handledType() {
return _baseType.getRawClass();
}
@Override
public boolean isCachable() { return true; }
/**
* Overridden to return true for those instances that are
* handling value for which Object Identity handling is enabled
* (either via value type or referring property).
*/
@Override
public ObjectIdReader getObjectIdReader() {
return _objectIdReader;
}
/**
* Method called by <code>BeanDeserializer</code> to resolve back reference
* part of managed references.
*/
@Override
public SettableBeanProperty findBackReference(String logicalName) {
return (_backRefProperties == null) ? null : _backRefProperties.get(logicalName);
}
/*
/**********************************************************
/* Deserializer implementation
/**********************************************************
*/
@Override
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException
{
// Hmmh. One tricky question; for scalar, is it an Object Id, or "Natural" type?
// for now, prefer Object Id:
if (_objectIdReader != null) {
JsonToken t = p.getCurrentToken();
if (t != null) {
// Most commonly, a scalar (int id, uuid String, ...)
if (t.isScalarValue()) {
return _deserializeFromObjectId(p, ctxt);
}
// but, with 2.5+, a simple Object-wrapped value also legal:
if (t == JsonToken.START_OBJECT) {
t = p.nextToken();
}
if ((t == JsonToken.FIELD_NAME) && _objectIdReader.maySerializeAsObject()
&& _objectIdReader.isValidReferencePropertyName(p.getCurrentName(), p)) {
return _deserializeFromObjectId(p, ctxt);
}
}
}
// First: support "natural" values (which are always serialized without type info!)
Object result = _deserializeIfNatural(p, ctxt);
if (result != null) {
return result;
}
return typeDeserializer.deserializeTypedFromObject(p, ctxt);
}
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException
{
// This method should never be called...
throw ctxt.instantiationException(_baseType.getRawClass(),
"abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information");
}
/*
/**********************************************************
/* Internal methods
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
return new SimpleType(raw, null,
// 18-Oct-2015, tatu: Should be ok to omit possible super-types, right?
null, null, null, null, false);
}
/**
* Method that should NOT to be used by application code:
* it does NOT properly handle inspection of super-types, so neither parent
* Classes nor implemented Interfaces are accessible with resulting type
* instance. Instead, please use {@link TypeFactory}'s <code>constructType</code>
* methods which handle introspection appropriately.
*<p>
* Note that prior to 2.7, method usage was not limited and would typically
* have worked acceptably: the problem comes from inability to resolve super-type
* information, for which {@link TypeFactory} is needed.
*
* @deprecated Since 2.7
*/
@Deprecated
public static SimpleType construct(Class<?> cls)
{
/* Let's add sanity checks, just to ensure no
* Map/Collection entries are constructed
*/
if (Map.class.isAssignableFrom(cls)) {
throw new IllegalArgumentException("Can not construct SimpleType for a Map (class: "+cls.getName()+")");
}
if (Collection.class.isAssignableFrom(cls)) {
throw new IllegalArgumentException("Can not construct SimpleType for a Collection (class: "+cls.getName()+")");
}
// ... and while we are at it, not array types either
if (cls.isArray()) {
throw new IllegalArgumentException("Can not construct SimpleType for an array (class: "+cls.getName()+")");
}
TypeBindings b = TypeBindings.emptyBindings();
return new SimpleType(cls, b,
_buildSuperClass(cls.getSuperclass(), b), null, null, null, false);
}
@Override
@Deprecated
protected JavaType _narrow(Class<?> subclass)
{
if (_class == subclass) {
return this;
}
// Should we check that there is a sub-class relationship?
// 15-Jan-2016, tatu: Almost yes, but there are some complications with
// placeholder values (`Void`, `NoClass`), so can not quite do yet.
// TODO: fix in 2.8
if (!_class.isAssignableFrom(subclass)) {
/*
throw new IllegalArgumentException("Class "+subclass.getName()+" not sub-type of "
+_class.getName());
*/
return new SimpleType(subclass, _bindings, this, _superInterfaces,
_valueHandler, _typeHandler, _asStatic);
}
// Otherwise, stitch together the hierarchy. First, super-class
Class<?> next = subclass.getSuperclass();
if
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> (next == _class) { // straight up parent class? Great.
return new SimpleType(subclass, _bindings, this,
_superInterfaces, _valueHandler, _typeHandler, _asStatic);
}
if ((next != null) && _class.isAssignableFrom(next)) {
JavaType superb = _narrow(next);
return new SimpleType(subclass, _bindings, superb,
null, _valueHandler, _typeHandler, _asStatic);
}
// if not found, try a super-interface
Class<?>[] nextI = subclass.getInterfaces();
for (Class<?> iface : nextI) {
if (iface == _class) { // directly implemented
return new SimpleType(subclass, _bindings, null,
new JavaType[] { this }, _valueHandler, _typeHandler, _asStatic);
}
if (_class.isAssignableFrom(iface)) { // indirect, so recurse
JavaType superb = _narrow(iface);
return new SimpleType(subclass, _bindings, null,
new JavaType[] { superb }, _valueHandler, _typeHandler, _asStatic);
}
}
// should not get here but...
throw new IllegalArgumentException("Internal error: Can not resolve sub-type for Class "+subclass.getName()+" to "
+_class.getName());
}
@Override
public JavaType withContentType(JavaType contentType) {
throw new IllegalArgumentException("Simple types have no content types; can not call withContentType()");
}
@Override
public SimpleType withTypeHandler(Object h) {
if (_typeHandler == h) {
return this;
}
return new SimpleType(_class, _bindings, _superClass, _superInterfaces, _valueHandler, h, _asStatic);
}
@Override
public JavaType withContentTypeHandler(Object h) {
// no content type, so:
throw new IllegalArgumentException("Simple types have no content types; can not call withContenTypeHandler()");
}
@Override
public SimpleType withValueHandler(Object h) {
if (h == _valueHandler) {
return this;
}
return new SimpleType(_class, _bindings, _superClass, _superInterfaces, h, _typeHandler, _asStatic);
}
@Override
public SimpleType withContentValueHandler(Object h) {
// no content type, so:
throw new IllegalArgumentException("Simple types have no content types; can not call withContenValueHandler()");
}
@Override
public SimpleType withStaticTyping() {
return _asStatic ? this : new SimpleType(_class, _bindings,
_superClass, _superInterfaces, _valueHandler, _typeHandler, true);
}
@Override
public Java
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> new POJOPropertyBuilder(_config, _annotationIntrospector, _forSerialization,
PropertyName.construct(implName));
props.put(implName, prop);
}
return prop;
}
private PropertyNamingStrategy _findNamingStrategy()
{
Object namingDef = (_annotationIntrospector == null)? null
: _annotationIntrospector.findNamingStrategy(_classDef);
if (namingDef == null) {
return _config.getPropertyNamingStrategy();
}
if (namingDef instanceof PropertyNamingStrategy) {
return (PropertyNamingStrategy) namingDef;
}
/* Alas, there's no way to force return type of "either class
* X or Y" -- need to throw an exception after the fact
*/
if (!(namingDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned PropertyNamingStrategy definition of type "
+namingDef.getClass().getName()+"; expected type PropertyNamingStrategy or Class<PropertyNamingStrategy> instead");
}
Class<?> namingClass = (Class<?>)namingDef;
// 09-Nov-2015, tatu: Need to consider pseudo-value of STD, which means "use default"
if (namingClass == PropertyNamingStrategy.class) {
return null;
}
if (!PropertyNamingStrategy.class.isAssignableFrom(namingClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "
+namingClass.getName()+"; expected Class<PropertyNamingStrategy>");
}
HandlerInstantiator hi = _config.getHandlerInstantiator();
if (hi != null) {
PropertyNamingStrategy pns = hi.namingStrategyInstance(_config, _classDef, namingClass);
if (pns != null) {
return pns;
}
}
return (PropertyNamingStrategy) ClassUtil.createInstance(namingClass,
_config.canOverrideAccessModifiers());
}
protected void _updateCreatorProperty(POJOPropertyBuilder prop, List<POJOPropertyBuilder> creatorProperties) {
if (creatorProperties != null) {
for (int i = 0, len = creatorProperties.size(); i < len; ++i) {
if (creatorProperties.get(i).getInternalName().equals(prop.getInternalName())) {
creatorProperties.set(i, prop);
break;
}
}
}
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> superInterfaces, _elementType,
_valueHandler, _typeHandler, _asStatic);
}
/*
/**********************************************************
/* Public API
/**********************************************************
*/
@Override
public boolean isContainerType() { return true; }
@Override
public boolean isCollectionLikeType() { return true; }
@Override
public JavaType getContentType() { return _elementType; }
@Override
public Object getContentValueHandler() {
return _elementType.getValueHandler();
}
@Override
public Object getContentTypeHandler() {
return _elementType.getTypeHandler();
}
@Override
public StringBuilder getErasedSignature(StringBuilder sb) {
return _classSignature(_class, sb, true);
}
@Override
public StringBuilder getGenericSignature(StringBuilder sb) {
_classSignature(_class, sb, false);
sb.append('<');
_elementType.getGenericSignature(sb);
sb.append(">;");
return sb;
}
@Override
protected String buildCanonicalName() {
StringBuilder sb = new StringBuilder();
sb.append(_class.getName());
if (_elementType != null) {
sb.append('<');
sb.append(_elementType.toCanonical());
sb.append('>');
}
return sb.toString();
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
/**
* Method that can be used for checking whether this type is a
* "real" Collection type; meaning whether it represents a parameterized
* subtype of {@link java.util.Collection} or just something that acts
* like one.
*/
public boolean isTrueCollectionType() {
return Collection.class.isAssignableFrom(_class);
}
/*
/**********************************************************
/* Standard methods
/**********************************************************
*/
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != getClass()) return false;
CollectionLikeType other = (CollectionLikeType) o;
return (_class == other._class) && _elementType.equals(other._elementType);
}
@Override
public String toString()
{
return "[collection-like type; class "+_class.getName()+", contains "+_elementType+"]";
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> able to optimize bit more in future...
return defaultInstance().constructType(t).getRawClass();
}
/*
/**********************************************************
/* Low-level helper methods
/**********************************************************
*/
/**
* Low-level lookup method moved from {@link com.fasterxml.jackson.databind.util.ClassUtil},
* to allow for overriding of lookup functionality in environments like OSGi.
*
* @since 2.6
*/
public Class<?> findClass(String className) throws ClassNotFoundException
{
if (className.indexOf('.') < 0) {
Class<?> prim = _findPrimitive(className);
if (prim != null) {
return prim;
}
}
// Two-phase lookup: first using context ClassLoader; then default
Throwable prob = null;
ClassLoader loader = this.getClassLoader();
if (loader == null) {
loader = Thread.currentThread().getContextClassLoader();
}
if (loader != null) {
try {
return classForName(className, true, loader);
} catch (Exception e) {
prob = ClassUtil.getRootCause(e);
}
}
try {
return classForName(className);
} catch (Exception e) {
if (prob == null) {
prob = ClassUtil.getRootCause(e);
}
}
if (prob instanceof RuntimeException) {
throw (RuntimeException) prob;
}
throw new ClassNotFoundException(prob.getMessage(), prob);
}
protected Class<?> classForName(String name, boolean initialize,
ClassLoader loader) throws ClassNotFoundException {
return Class.forName(name, true, loader);
}
protected Class<?> classForName(String name) throws ClassNotFoundException {
return Class.forName(name);
}
protected Class<?> _findPrimitive(String className)
{
if ("int".equals(className)) return Integer.TYPE;
if ("long".equals(className)) return Long.TYPE;
if ("float".equals(className)) return Float.TYPE;
if ("double".equals(className)) return Double.TYPE;
if ("boolean".equals(className)) return Boolean.TYPE;
if ("byte".equals(className)) return Byte.TYPE;
if ("char".equals(className)) return Character.TYPE;
if ("short".equals(className)) return Short.TYPE;
if ("void".equals(className)) return Void.TYPE;
return null;
}
/*
/**********************************************************
/* Type conversion, parameterization resolution methods
/**********************************************************
*/
/**
* Factory method for creating a subtype of given base type, as defined
* by specified subclass; but retaining generic type information if any.
* Can be used, for example, to get equivalent of "HashMap<String,
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>Integer>"
* from "Map<String,Integer>" by giving <code>HashMap.class</code>
* as subclass.
*/
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass)
{
// simple optimization to avoid costly introspection if type-erased type does NOT differ
final Class<?> rawBase = baseType.getRawClass();
if (rawBase == subclass) {
return baseType;
}
JavaType newType;
// also: if we start from untyped, not much to save
do { // bogus loop to be able to break
if (rawBase == Object.class) {
newType = _fromClass(null, subclass, TypeBindings.emptyBindings());
break;
}
if (!rawBase.isAssignableFrom(subclass)) {
throw new IllegalArgumentException(String.format(
"Class %s not subtype of %s", subclass.getName(), baseType));
}
// A few special cases where we can simplify handling:
// (1) Original target type has no generics -- just resolve subtype
if (baseType.getBindings().isEmpty()) {
newType = _fromClass(null, subclass, TypeBindings.emptyBindings());
break;
}
// (2) A small set of "well-known" List/Map subtypes where can take a short-cut
if (baseType.isContainerType()) {
if (baseType.isMapLikeType()) {
if ((subclass == HashMap.class)
|| (subclass == LinkedHashMap.class)
|| (subclass == EnumMap.class)
|| (subclass == TreeMap.class)) {
newType = _fromClass(null, subclass,
TypeBindings.create(subclass, baseType.getKeyType(), baseType.getContentType()));
break;
}
} else if (baseType.isCollectionLikeType()) {
if ((subclass == ArrayList.class)
|| (subclass == LinkedList.class)
|| (subclass == HashSet.class)
|| (subclass == TreeSet.class)) {
newType = _fromClass(null, subclass,
TypeBindings.create(subclass, baseType.getContentType()));
break;
}
// 29-Oct-2015, tatu: One further shortcut: there are variants of `EnumSet`,
// but they are impl details and we basically do not care...
if (rawBase == EnumSet.class) {
return baseType;
}
}
}
// (3) Sub-class does not take type parameters -- just resolve subtype
int typeParamCount = subclass.getTypeParameters().length;
if (typeParamCount == 0) {
newType = _fromClass(
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>.class.isAssignableFrom(subclass)
|| Collection.class.isAssignableFrom(subclass)) {
// need to assert type compatibility...
if (!baseType.getRawClass().isAssignableFrom(subclass)) {
throw new IllegalArgumentException("Class "+subclass.getClass().getName()+" not subtype of "+baseType);
}
// this _should_ work, right?
JavaType subtype = _fromClass(null, subclass, TypeBindings.emptyBindings());
// one more thing: handlers to copy?
Object h = baseType.getValueHandler();
if (h != null) {
subtype = subtype.withValueHandler(h);
}
h = baseType.getTypeHandler();
if (h != null) {
subtype = subtype.withTypeHandler(h);
}
return subtype;
}
}
// But there is the need for special case for arrays too, it seems
if (baseType instanceof ArrayType) {
if (subclass.isArray()) {
// actually see if it might be a no-op first:
ArrayType at = (ArrayType) baseType;
Class<?> rawComp = subclass.getComponentType();
if (at.getContentType().getRawClass() == rawComp) {
return baseType;
}
JavaType componentType = _fromAny(null, rawComp, null);
return ((ArrayType) baseType).withComponentType(componentType);
}
}
// otherwise regular narrowing should work just fine
return baseType.narrowBy(subclass);
*/
}
/**
* Method similar to {@link #constructSpecializedType}, but that creates a
* less-specific type of given type. Usually this is as simple as simply
* finding super-type with type erasure of <code>superClass</code>, but
* there may be need for some additional work-arounds.
*
* @param superClass
*
* @since 2.7
*/
public JavaType constructGeneralizedType(JavaType baseType, Class<?> superClass)
{
// simple optimization to avoid costly introspection if type-erased type does NOT differ
final Class<?> rawBase = baseType.getRawClass();
if (rawBase == superClass) {
return baseType;
}
JavaType superType = baseType.findSuperType(superClass);
if (superType == null) {
// Most likely, caller did not verify sub/super-type relationship
if (!superClass.isAssignableFrom(rawBase)) {
throw new IllegalArgumentException(String.format(
"Class %s not a super-type of %s", superClass.getName(), baseType));
}
// 01-Nov-2015, tatu: Should never happen, but ch
throw new IllegalArgumentException(String.format(
"Internal error
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>: class %s not included as super-type for %s",
superClass.getName(), baseType));
}
return superType;
}
/**
* Factory method for constructing a {@link JavaType} out of its canonical
* representation (see {@link JavaType#toCanonical()}).
*
* @param canonical Canonical string representation of a type
*
* @throws IllegalArgumentException If canonical representation is malformed,
* or class that type represents (including its generic parameters) is
* not found
*/
public JavaType constructFromCanonical(String canonical) throws IllegalArgumentException
{
return _parser.parse(canonical);
}
/**
* Method that is to figure out actual type parameters that given
* class binds to generic types defined by given (generic)
* interface or class.
* This could mean, for example, trying to figure out
* key and value types for Map implementations.
*
* @param type Sub-type (leaf type) that implements <code>expType</code>
*/
public JavaType[] findTypeParameters(JavaType type, Class<?> expType)
{
JavaType match = type.findSuperType(expType);
if (match == null) {
return NO_TYPES;
}
return match.getBindings().typeParameterArray();
}
/**
* @deprecated Since 2.7 resolve raw type first, then find type parameters
*/
@Deprecated // since 2.7
public JavaType[] findTypeParameters(Class<?> clz, Class<?> expType, TypeBindings bindings) {
return findTypeParameters(constructType(clz, bindings), expType);
}
/**
* @deprecated Since 2.7 resolve raw type first, then find type parameters
*/
@Deprecated // since 2.7
public JavaType[] findTypeParameters(Class<?> clz, Class<?> expType) {
return findTypeParameters(constructType(clz), expType);
}
/**
* Method that can be called to figure out more specific of two
* types (if they are related; that is, one implements or extends the
* other); or if not related, return the primary type.
*
* @param type1 Primary type to consider
* @param type2 Secondary type to consider
*
* @since 2.2
*/
public JavaType moreSpecificType(JavaType type1, JavaType type2)
{
if (type1 == null) {
return type2;
}
if (type2 == null) {
return type1;
}
Class<?> raw1 = type1.getRawClass();
Class<?> raw2 = type2.getRawClass();
if (raw1 == raw2) {
return type1
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>;
}
// TODO: maybe try sub-classing, to retain generic types?
if (raw1.isAssignableFrom(raw2)) {
return type2;
}
return type1;
}
/*
/**********************************************************
/* Public factory methods
/**********************************************************
*/
public JavaType constructType(Type type) {
return _fromAny(null, type, EMPTY_BINDINGS);
}
public JavaType constructType(Type type, TypeBindings bindings) {
return _fromAny(null, type, bindings);
}
public JavaType constructType(TypeReference<?> typeRef)
{
// 19-Oct-2015, tatu: Simpler variant like so should work
return _fromAny(null, typeRef.getType(), EMPTY_BINDINGS);
// but if not, due to funky sub-classing, type variables, what follows
// is a more complete processing a la Java ClassMate.
/*
final Class<?> refdRawType = typeRef.getClass();
JavaType type = _fromClass(null, refdRawType, EMPTY_BINDINGS);
JavaType genType = type.findSuperType(TypeReference.class);
if (genType == null) { // sanity check; shouldn't occur
throw new IllegalArgumentException("Unparameterized GenericType instance ("+refdRawType.getName()+")");
}
TypeBindings b = genType.getBindings();
JavaType[] params = b.typeParameterArray();
if (params.length == 0) {
throw new IllegalArgumentException("Unparameterized GenericType instance ("+refdRawType.getName()+")");
}
return params[0];
*/
}
/**
* @deprecated Since 2.7 (accidentally removed in 2.7.0; added back in 2.7.1)
*/
@Deprecated
public JavaType constructType(Type type, Class<?> contextClass) {
TypeBindings bindings = (contextClass == null)
? TypeBindings.emptyBindings() : constructType(contextClass).getBindings();
return _fromAny(null, type, bindings);
}
/**
* @deprecated Since 2.7 (accidentally removed in 2.7.0; added back in 2.7.1)
*/
@Deprecated
public JavaType constructType(Type type, JavaType contextType) {
TypeBindings bindings = (contextType == null)
? TypeBindings.emptyBindings() : contextType.getBindings();
return _fromAny(null, type, bindings);
}
/*
/**********************************************************
/* Direct factory methods
/**********************************************************
*/
/**
* Method for constructing an {@link ArrayType}.
*<p
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>BeanType(type.getRawClass())) {
return null;
}
// Use generic bean introspection to build deserializer
return buildBeanDeserializer(ctxt, type, beanDesc);
}
@Override
public JsonDeserializer<Object> createBuilderBasedDeserializer(
DeserializationContext ctxt, JavaType valueType, BeanDescription beanDesc,
Class<?> builderClass)
throws JsonMappingException
{
// First: need a BeanDescription for builder class
JavaType builderType = ctxt.constructType(builderClass);
BeanDescription builderDesc = ctxt.getConfig().introspectForBuilder(builderType);
return buildBuilderBasedDeserializer(ctxt, valueType, builderDesc);
}
/**
* Method called by {@link BeanDeserializerFactory} to see if there might be a standard
* deserializer registered for given type.
*/
protected JsonDeserializer<?> findStdDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
// note: we do NOT check for custom deserializers here, caller has already
// done that
JsonDeserializer<?> deser = findDefaultDeserializer(ctxt, type, beanDesc);
// Also: better ensure these are post-processable?
if (deser != null) {
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyDeserializer(ctxt.getConfig(), beanDesc, deser);
}
}
}
return deser;
}
protected JavaType materializeAbstractType(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
// May have multiple resolvers, call in precedence order until one returns non-null
for (AbstractTypeResolver r : _factoryConfig.abstractTypeResolvers()) {
JavaType concrete = r.resolveAbstractType(ctxt.getConfig(), beanDesc);
if (concrete != null) {
return concrete;
}
}
return null;
}
/*
/**********************************************************
/* Public construction method beyond DeserializerFactory API:
/* can be called from outside as well as overridden by
/* sub-classes
/**********************************************************
*/
/**
* Method that is to actually build a bean deserializer instance.
* All basic sanity checks have been done to know that what we have
* may be a valid bean type, and that there are no default simple
* deserializers.
*/
@SuppressWarnings("unchecked")
public JsonDeserializer<Object> buildBeanDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
// First: check what creators we can use, if any
ValueInstantiator valueInstantiator;
/* 04-Jun-20
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> propDef.getGetter();
// should only consider Collections and Maps, for now?
Class<?> rawPropertyType = getter.getRawType();
if (Collection.class.isAssignableFrom(rawPropertyType)
|| Map.class.isAssignableFrom(rawPropertyType)) {
prop = constructSetterlessProperty(ctxt, beanDesc, propDef);
}
}
// 25-Sep-2014, tatu: No point in finding constructor parameters for abstract types
// (since they are never used anyway)
if (isConcrete && propDef.hasConstructorParameter()) {
/* [JACKSON-700] If property is passed via constructor parameter, we must
* handle things in special way. Not sure what is the most optimal way...
* for now, let's just call a (new) method in builder, which does nothing.
*/
// but let's call a method just to allow custom builders to be aware...
final String name = propDef.getName();
CreatorProperty cprop = null;
if (creatorProps != null) {
for (SettableBeanProperty cp : creatorProps) {
if (name.equals(cp.getName()) && (cp instanceof CreatorProperty)) {
cprop = (CreatorProperty) cp;
break;
}
}
}
if (cprop == null) {
throw ctxt.mappingException("Could not find creator property with name '%s' (in class %s)",
name, beanDesc.getBeanClass().getName());
}
if (prop != null) {
cprop.setFallbackSetter(prop);
}
prop = cprop;
builder.addCreatorProperty(cprop);
continue;
}
if (prop != null) {
Class<?>[] views = propDef.findViews();
if (views == null) {
// one more twist: if default inclusion disabled, need to force empty set of views
if (!ctxt.isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION)) {
views = NO_VIEWS;
}
}
// one more thing before adding to builder: copy any metadata
prop.setViews(views);
builder.addProperty(prop);
}
}
}
/**
* Helper method called to filter out explicit ignored properties,
* as well as properties that have "ignorable types".
* Note that this will not remove properties that have no
* setters.
*/
protected List<BeanPropertyDefinition> filterBeanProps(DeserializationContext ctxt,
BeanDescription beanDesc, BeanDeserializerBuilder builder,
List<BeanPropertyDefinition> propDefsIn,
Set<String> ignored)
throws JsonMappingException
{
ArrayList<BeanPropertyDefinition> result = new ArrayList<BeanPropertyDefinition>(
Math.
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> creating new serializers
* as need be),
*
* @param rootType Type to use for locating serializer to use, instead of actual
* runtime type. Must be actual type, or one of its super types
*/
public void serializeValue(JsonGenerator gen, Object value, JavaType rootType) throws IOException
{
if (value == null) {
_serializeNull(gen);
return;
}
// Let's ensure types are compatible at this point
if (!rootType.getRawClass().isAssignableFrom(value.getClass())) {
_reportIncompatibleRootType(value, rootType);
}
// root value, not reached via property:
JsonSerializer<Object> ser = findTypedValueSerializer(rootType, true, null);
// Ok: should we wrap result in an additional property ("root name")?
final boolean wrap;
PropertyName rootName = _config.getFullRootName();
if (rootName == null) { // not explicitly specified
// [JACKSON-163]
wrap = _config.isEnabled(SerializationFeature.WRAP_ROOT_VALUE);
if (wrap) {
gen.writeStartObject();
PropertyName pname = _config.findRootName(value.getClass());
gen.writeFieldName(pname.simpleAsEncoded(_config));
}
} else if (rootName.isEmpty()) {
wrap = false;
} else { // [JACKSON-764]
// empty String means explicitly disabled; non-empty that it is enabled
wrap = true;
gen.writeStartObject();
gen.writeFieldName(rootName.getSimpleName());
}
try {
ser.serialize(value, gen, this);
if (wrap) {
gen.writeEndObject();
}
} catch (IOException ioe) { // no wrapping for IO (and derived)
throw ioe;
} catch (Exception e) { // but others do need to be, to get path etc
String msg = e.getMessage();
if (msg == null) {
msg = "[no message for "+e.getClass().getName()+"]";
}
throw JsonMappingException.from(gen, msg, e);
}
}
/**
* The method to be called by {@link ObjectWriter}
* for serializing given value (assumed to be of specified root type,
* instead of runtime type of value), when it may know specific
* {@link JsonSerializer} to use.
*
* @param rootType Type to use for locating serializer to use, instead of actual
* runtime type, if no serializer is passed
* @param ser Root Serializer to use, if not null
*
* @since 2.1
*/
public void serializeValue(JsonGenerator gen
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>, Object value, JavaType rootType,
JsonSerializer<Object> ser) throws IOException
{
if (value == null) {
_serializeNull(gen);
return;
}
// Let's ensure types are compatible at this point
if ((rootType != null) && !rootType.getRawClass().isAssignableFrom(value.getClass())) {
_reportIncompatibleRootType(value, rootType);
}
// root value, not reached via property:
if (ser == null) {
ser = findTypedValueSerializer(rootType, true, null);
}
// Ok: should we wrap result in an additional property ("root name")?
final boolean wrap;
PropertyName rootName = _config.getFullRootName();
if (rootName == null) { // not explicitly specified
// [JACKSON-163]
wrap = _config.isEnabled(SerializationFeature.WRAP_ROOT_VALUE);
if (wrap) {
gen.writeStartObject();
PropertyName pname = (rootType == null)
? _config.findRootName(value.getClass())
: _config.findRootName(rootType);
gen.writeFieldName(pname.simpleAsEncoded(_config));
}
} else if (rootName.isEmpty()) {
wrap = false;
} else { // [JACKSON-764]
// empty String means explicitly disabled; non-empty that it is enabled
wrap = true;
gen.writeStartObject();
gen.writeFieldName(rootName.getSimpleName());
}
try {
ser.serialize(value, gen, this);
if (wrap) {
gen.writeEndObject();
}
} catch (IOException ioe) { // no wrapping for IO (and derived)
throw ioe;
} catch (Exception e) { // but others do need to be, to get path etc
String msg = e.getMessage();
if (msg == null) {
msg = "[no message for "+e.getClass().getName()+"]";
}
throw JsonMappingException.from(gen, msg, e);
}
}
/**
* Alternate serialization call used for polymorphic types, when {@link TypeSerializer}
* is already known, but the actual serializer may or may not be.
*
* @since 2.6
*/
public void serializePolymorphic(JsonGenerator gen, Object value, JavaType rootType,
JsonSerializer<Object> valueSer, TypeSerializer typeSer)
throws IOException
{
if (value == null) {
_serializeNull(gen);
return;
}
// Let's ensure types are compatible at this point
if ((rootType != null) && !rootType.getRawClass().isAssignableFrom(value.getClass())) {
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>canUseFor(generatorType)) {
generator = gen;
break;
}
}
}
if (generator == null) {
generator = generatorType.newForSerialization(this);
_objectIdGenerators.add(generator);
}
WritableObjectId oid = new WritableObjectId(generator);
_seenObjectIds.put(forPojo, oid);
return oid;
}
/**
* Overridable helper method used for creating {@link java.util.Map}
* used for storing mappings from serializable objects to their
* Object Ids.
*
* @since 2.3
*/
protected Map<Object,WritableObjectId> _createObjectIdMap()
{
/* 06-Aug-2013, tatu: We may actually want to use equality,
* instead of identity... so:
*/
if (isEnabled(SerializationFeature.USE_EQUALITY_FOR_OBJECT_ID)) {
return new HashMap<Object,WritableObjectId>();
}
return new IdentityHashMap<Object,WritableObjectId>();
}
/*
/**********************************************************
/* Factory method impls
/**********************************************************
*/
@Override
public JsonSerializer<Object> serializerInstance(Annotated annotated, Object serDef) throws JsonMappingException
{
if (serDef == null) {
return null;
}
JsonSerializer<?> ser;
if (serDef instanceof JsonSerializer) {
ser = (JsonSerializer<?>) serDef;
} else {
/* Alas, there's no way to force return type of "either class
* X or Y" -- need to throw an exception after the fact
*/
if (!(serDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned serializer definition of type "
+serDef.getClass().getName()+"; expected type JsonSerializer or Class<JsonSerializer> instead");
}
Class<?> serClass = (Class<?>)serDef;
// there are some known "no class" markers to consider too:
if (serClass == JsonSerializer.None.class || ClassUtil.isBogusClass(serClass)) {
return null;
}
if (!JsonSerializer.class.isAssignableFrom(serClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "
+serClass.getName()+"; expected Class<JsonSerializer>");
}
HandlerInstantiator hi = _config.getHandlerInstantiator();
ser = (hi == null) ? null : hi.serializerInstance(_config, annotated, serClass);
if (ser == null) {
ser = (JsonSerializer<?>) ClassUtil.createInstance(serClass,
_config.canOverrideAccessModifiers());
}
}
return (JsonSerializer<Object>) _handleResolvable(ser);
}
/*
/********************************************************
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.KeyDeserializers;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.EnumResolver;
/**
* Helper class used to contain simple/well-known key deserializers.
* Following kinds of Objects can be handled currently:
*<ul>
* <li>Primitive wrappers (Boolean, Byte, Char, Short, Integer, Float, Long, Double)</li>
* <li>Enums (usually not needed, since EnumMap doesn't call us)</li>
* <li>{@link java.util.Date}</li>
* <li>{@link java.util.Calendar}</li>
* <li>{@link java.util.UUID}</li>
* <li>{@link java.util.Locale}</li>
* <li>Anything with constructor that takes a single String arg
* (if not explicitly @JsonIgnore'd)</li>
* <li>Anything with {@code static T valueOf(String)} factory method
* (if not explicitly @JsonIgnore'd)</li>
*</ul>
*/
public class StdKeyDeserializers
implements KeyDeserializers, java.io.Serializable
{
private static final long serialVersionUID = 1L;
public static KeyDeserializer constructEnumKeyDeserializer(EnumResolver enumResolver) {
return new StdKeyDeserializer.EnumKD(enumResolver, null);
}
public static KeyDeserializer constructEnumKeyDeserializer(EnumResolver enumResolver,
AnnotatedMethod factory) {
return new StdKeyDeserializer.EnumKD(enumResolver, factory);
}
public static KeyDeserializer constructDelegatingKeyDeserializer(DeserializationConfig config,
JavaType type, JsonDeserializer<?> deser)
{
return new StdKeyDeserializer.DelegatingKD(type.getRawClass(), deser);
}
public static KeyDeserializer findStringBasedKeyDeserializer(DeserializationConfig config,
JavaType type)
{
/* We don't need full deserialization information, just need to
* know creators.
*/
BeanDescription beanDesc = config.introspect(type);
// Ok, so: can we find T(String) constructor?
Constructor<?> ctor = beanDesc.findSingleArgConstructor(String.class);
if (ctor != null) {
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(ctor, config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
}
return new Std
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>KeyDeserializer.StringCtorKeyDeserializer(ctor);
}
/* or if not, "static T valueOf(String)" (or equivalent marked
* with @JsonCreator annotation?)
*/
Method m = beanDesc.findFactoryMethod(String.class);
if (m != null){
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(m, config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
}
return new StdKeyDeserializer.StringFactoryKeyDeserializer(m);
}
// nope, no such luck...
return null;
}
/*
/**********************************************************
/* KeyDeserializers implementation
/**********************************************************
*/
@Override
public KeyDeserializer findKeyDeserializer(JavaType type,
DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException
{
Class<?> raw = type.getRawClass();
// 23-Apr-2013, tatu: Map primitive types, just in case one was given
if (raw.isPrimitive()) {
raw = ClassUtil.wrapperType(raw);
}
return StdKeyDeserializer.forType(raw);
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
/**
* Standard deserializer for {@link EnumSet}s.
* <p>
* Note: casting within this class is all messed up -- just could not figure out a way
* to properly deal with recursive definition of "EnumSet<K extends Enum<K>, V>
*/
@SuppressWarnings("rawtypes")
public class EnumSetDeserializer
extends StdDeserializer<EnumSet<?>>
implements ContextualDeserializer
{
private static final long serialVersionUID = 1L; // since 2.5
protected final JavaType _enumType;
protected final Class<Enum> _enumClass;
protected JsonDeserializer<Enum<?>> _enumDeserializer;
/**
* Specific override for this instance (from proper, or global per-type overrides)
* to indicate whether single value may be taken to mean an unwrapped one-element array
* or not. If null, left to global defaults.
*
* @since 2.7
*/
protected final Boolean _unwrapSingle;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
@SuppressWarnings("unchecked" )
public EnumSetDeserializer(JavaType enumType, JsonDeserializer<?> deser)
{
super(EnumSet.class);
_enumType = enumType;
_enumClass = (Class<Enum>) enumType.getRawClass();
// sanity check
if (!_enumClass.isEnum()) {
throw new IllegalArgumentException("Type "+enumType+" not Java Enum type");
}
_enumDeserializer = (JsonDeserializer<Enum<?>>) deser;
_unwrapSingle = null;
}
/**
* @since 2.7
*/
@SuppressWarnings("unchecked" )
protected EnumSetDeserializer(EnumSetDeserializer base,
JsonDeserializer<?> deser, Boolean unwrapSingle) {
super(EnumSet.class);
_enumType = base._enumType;
_enumClass = base._enumClass;
_enumDeserializer = (JsonDeserializer<Enum<?>>) deser;
_unwrapSingle = unwrapSingle;
}
public EnumSetDeserializer withDeserializer(JsonDeserializer<?> deser) {
if (_enumDeserializer == deser) {
return this;
}
return new EnumSetDeserializer(this, deser, _unwrapSingle);
}
public EnumSetDeserializer withResolved(JsonDeserializer<?> deser, Boolean unwrapSingle
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>;
}
/**
* Method for getting current {@link SerializerFactoryConfig}.
*<p>
* Note that since instances are immutable, you can NOT change settings
* by accessing an instance and calling methods: this will simply create
* new instance of config object.
*/
public SerializerFactoryConfig getFactoryConfig() {
return _factoryConfig;
}
/**
* Method used for creating a new instance of this factory, but with different
* configuration. Reason for specifying factory method (instead of plain constructor)
* is to allow proper sub-classing of factories.
*<p>
* Note that custom sub-classes generally <b>must override</b> implementation
* of this method, as it usually requires instantiating a new instance of
* factory type. Check out javadocs for
* {@link com.fasterxml.jackson.databind.ser.BeanSerializerFactory} for more details.
*/
public abstract SerializerFactory withConfig(SerializerFactoryConfig config);
/**
* Convenience method for creating a new factory instance with an additional
* serializer provider.
*/
@Override
public final SerializerFactory withAdditionalSerializers(Serializers additional) {
return withConfig(_factoryConfig.withAdditionalSerializers(additional));
}
/**
* Convenience method for creating a new factory instance with an additional
* key serializer provider.
*/
@Override
public final SerializerFactory withAdditionalKeySerializers(Serializers additional) {
return withConfig(_factoryConfig.withAdditionalKeySerializers(additional));
}
/**
* Convenience method for creating a new factory instance with additional bean
* serializer modifier.
*/
@Override
public final SerializerFactory withSerializerModifier(BeanSerializerModifier modifier) {
return withConfig(_factoryConfig.withSerializerModifier(modifier));
}
/*
/**********************************************************
/* SerializerFactory impl
/**********************************************************
*/
// Implemented by sub-classes
@Override
public abstract JsonSerializer<Object> createSerializer(SerializerProvider prov,
JavaType type)
throws JsonMappingException;
@Override
@SuppressWarnings("unchecked")
public JsonSerializer<Object> createKeySerializer(SerializationConfig config,
JavaType keyType, JsonSerializer<Object> defaultImpl)
{
// We should not need any member method info; at most class annotations for Map type
// ... at least, not here.
BeanDescription beanDesc = config.introspectClassAnnotations(keyType.getRawClass());
JsonSerializer<?> ser = null;
// Minor optimization: to avoid constructing beanDesc, bail out if none registered
if (_factoryConfig.hasKeySerializers()) {
// Only thing we have here are module-provided key serializers:
for (Serializers serializers : _factoryConfig.keySerializers()) {
ser = serializers.findSerializer(config, keyType, bean
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>Desc);
if (ser != null) {
break;
}
}
}
if (ser == null) {
ser = defaultImpl;
if (ser == null) {
ser = StdKeySerializers.getStdKeySerializer(config, keyType.getRawClass(), false);
// As per [databind#47], also need to support @JsonValue
if (ser == null) {
beanDesc = config.introspect(keyType);
AnnotatedMethod am = beanDesc.findJsonValueMethod();
if (am != null) {
final Class<?> rawType = am.getRawReturnType();
JsonSerializer<?> delegate = StdKeySerializers.getStdKeySerializer(config,
rawType, true);
Method m = am.getAnnotated();
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(m, config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
}
ser = new JsonValueSerializer(m, delegate);
} else {
ser = StdKeySerializers.getFallbackKeySerializer(config, keyType.getRawClass());
}
}
}
}
// [databind#120]: Allow post-processing
if (_factoryConfig.hasSerializerModifiers()) {
for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
ser = mod.modifyKeySerializer(config, keyType, beanDesc, ser);
}
}
return (JsonSerializer<Object>) ser;
}
/**
* Method called to construct a type serializer for values with given declared
* base type. This is called for values other than those of bean property
* types.
*/
@Override
public TypeSerializer createTypeSerializer(SerializationConfig config,
JavaType baseType)
{
BeanDescription bean = config.introspectClassAnnotations(baseType.getRawClass());
AnnotatedClass ac = bean.getClassInfo();
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findTypeResolver(config, ac, baseType);
/* Ok: if there is no explicit type info handler, we may want to
* use a default. If so, config object knows what to use.
*/
Collection<NamedType> subtypes = null;
if (b == null) {
b = config.getDefaultTyper(baseType);
} else {
subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(config, ac);
}
if (b == null) {
return null;
}
// 10-Jun-2015, tatu: Since not created for Bean Property, no need for post-processing
// wrt EXTERNAL_PROPERTY
return
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> b.buildTypeSerializer(config, baseType, subtypes);
}
/*
/**********************************************************
/* Additional API for other core classes
/**********************************************************
*/
protected abstract Iterable<Serializers> customSerializers();
/*
/**********************************************************
/* Overridable secondary serializer accessor methods
/**********************************************************
*/
/**
* Method that will use fast lookup (and identity comparison) methods to
* see if we know serializer to use for given type.
*/
protected final JsonSerializer<?> findSerializerByLookup(JavaType type,
SerializationConfig config, BeanDescription beanDesc,
boolean staticTyping)
{
Class<?> raw = type.getRawClass();
String clsName = raw.getName();
JsonSerializer<?> ser = _concrete.get(clsName);
if (ser == null) {
Class<? extends JsonSerializer<?>> serClass = _concreteLazy.get(clsName);
if (serClass != null) {
try {
return serClass.newInstance();
} catch (Exception e) {
throw new IllegalStateException("Failed to instantiate standard serializer (of type "+serClass.getName()+"): "
+e.getMessage(), e);
}
}
}
return ser;
}
/**
* Method called to see if one of primary per-class annotations
* (or related, like implementing of {@link JsonSerializable})
* determines the serializer to use.
*<p>
* Currently handles things like:
*<ul>
* <li>If type implements {@link JsonSerializable}, use that
* </li>
* <li>If type has {@link com.fasterxml.jackson.annotation.JsonValue} annotation (or equivalent), build serializer
* based on that property
* </li>
*</ul>
*
* @since 2.0
*/
protected final JsonSerializer<?> findSerializerByAnnotations(SerializerProvider prov,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
Class<?> raw = type.getRawClass();
// First: JsonSerializable?
if (JsonSerializable.class.isAssignableFrom(raw)) {
return SerializableSerializer.instance;
}
// Second: @JsonValue for any type
AnnotatedMethod valueMethod = beanDesc.findJsonValueMethod();
if (valueMethod != null) {
Method m = valueMethod.getAnnotated();
if (prov.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(m, prov.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
}
JsonSerializer<Object> ser = findSerializerFromAnnotation(prov, valueMethod);
return new JsonValueSerializer(m, ser);
}
// No well-known annotations...
return null;
}
/**
* Method for checking if we can determine
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> serializer to use based on set of
* known primary types, checking for set of known base types (exact matches
* having been compared against with <code>findSerializerByLookup</code>).
* This does not include "secondary" interfaces, but
* mostly concrete or abstract base classes.
*/
protected final JsonSerializer<?> findSerializerByPrimaryType(SerializerProvider prov,
JavaType type, BeanDescription beanDesc,
boolean staticTyping)
throws JsonMappingException
{
Class<?> raw = type.getRawClass();
// Then check for optional/external serializers
JsonSerializer<?> ser = findOptionalStdSerializer(prov, type, beanDesc, staticTyping);
if (ser != null) {
return ser;
}
if (Calendar.class.isAssignableFrom(raw)) {
return CalendarSerializer.instance;
}
if (java.util.Date.class.isAssignableFrom(raw)) {
return DateSerializer.instance;
}
if (Map.Entry.class.isAssignableFrom(raw)) {
// 18-Oct-2015, tatu: With 2.7, need to dig type info:
JavaType mapEntryType = type.findSuperType(Map.Entry.class);
// 28-Apr-2015, tatu: TypeFactory does it all for us already so
JavaType kt = mapEntryType.containedType(0);
if (kt == null) {
kt = TypeFactory.unknownType();
}
JavaType vt = mapEntryType.containedType(1);
if (vt == null) {
vt = TypeFactory.unknownType();
}
return buildMapEntrySerializer(prov.getConfig(), type, beanDesc, staticTyping, kt, vt);
}
if (ByteBuffer.class.isAssignableFrom(raw)) {
return new ByteBufferSerializer();
}
if (InetAddress.class.isAssignableFrom(raw)) {
return new InetAddressSerializer();
}
if (InetSocketAddress.class.isAssignableFrom(raw)) {
return new InetSocketAddressSerializer();
}
if (TimeZone.class.isAssignableFrom(raw)) {
return new TimeZoneSerializer();
}
if (java.nio.charset.Charset.class.isAssignableFrom(raw)) {
return ToStringSerializer.instance;
}
if (Number.class.isAssignableFrom(raw)) {
// 21-May-2014, tatu: Couple of alternatives actually
JsonFormat.Value format = beanDesc.findExpectedFormat(null);
if (format != null) {
switch (format.getShape()) {
case STRING:
return ToStringSerializer.instance;
case OBJECT: // need to bail out to let it be serialized as POJO
case ARRAY: // or, I guess ARRAY; otherwise no point in spec
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>ulating
return null;
default:
}
}
return NumberSerializer.instance;
}
if (Enum.class.isAssignableFrom(raw)) {
return buildEnumSerializer(prov.getConfig(), type, beanDesc);
}
return null;
}
/**
* Overridable method called after checking all other types.
*
* @since 2.2
*/
protected JsonSerializer<?> findOptionalStdSerializer(SerializerProvider prov,
JavaType type, BeanDescription beanDesc, boolean staticTyping)
throws JsonMappingException
{
return OptionalHandlerFactory.instance.findSerializer(prov.getConfig(), type, beanDesc);
}
/**
* Reflection-based serialized find method, which checks if
* given class implements one of recognized "add-on" interfaces.
* Add-on here means a role that is usually or can be a secondary
* trait: for example,
* bean classes may implement {@link Iterable}, but their main
* function is usually something else. The reason for
*/
protected final JsonSerializer<?> findSerializerByAddonType(SerializationConfig config,
JavaType javaType, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException
{
Class<?> rawType = javaType.getRawClass();
if (Iterator.class.isAssignableFrom(rawType)) {
JavaType[] params = config.getTypeFactory().findTypeParameters(javaType, Iterator.class);
JavaType vt = (params == null || params.length != 1) ?
TypeFactory.unknownType() : params[0];
return buildIteratorSerializer(config, javaType, beanDesc, staticTyping, vt);
}
if (Iterable.class.isAssignableFrom(rawType)) {
JavaType[] params = config.getTypeFactory().findTypeParameters(javaType, Iterable.class);
JavaType vt = (params == null || params.length != 1) ?
TypeFactory.unknownType() : params[0];
return buildIterableSerializer(config, javaType, beanDesc, staticTyping, vt);
}
if (CharSequence.class.isAssignableFrom(rawType)) {
return ToStringSerializer.instance;
}
return null;
}
/**
* Helper method called to check if a class or method
* has an annotation
* (@link com.fasterxml.jackson.databind.annotation.JsonSerialize#using)
* that tells the class to use for serialization.
* Returns null if no such annotation found.
*/
@SuppressWarnings("unchecked")
protected JsonSerializer<Object> findSerializerFromAnnotation(SerializerProvider prov,
Annotated a)
throws JsonMappingException
{
Object serDef = prov.getAnnotationIntrospector().findSerializer(a);
if (serDef == null) {
return null;
}
JsonSerializer<Object>
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> ser = prov.serializerInstance(a, serDef);
// One more thing however: may need to also apply a converter:
return (JsonSerializer<Object>) findConvertingSerializer(prov, a, ser);
}
/**
* Helper method that will check whether given annotated entity (usually class,
* but may also be a property accessor) indicates that a {@link Converter} is to
* be used; and if so, to construct and return suitable serializer for it.
* If not, will simply return given serializer as is.
*/
protected JsonSerializer<?> findConvertingSerializer(SerializerProvider prov,
Annotated a, JsonSerializer<?> ser)
throws JsonMappingException
{
Converter<Object,Object> conv = findConverter(prov, a);
if (conv == null) {
return ser;
}
JavaType delegateType = conv.getOutputType(prov.getTypeFactory());
return new StdDelegatingSerializer(conv, delegateType, ser);
}
protected Converter<Object,Object> findConverter(SerializerProvider prov,
Annotated a)
throws JsonMappingException
{
Object convDef = prov.getAnnotationIntrospector().findSerializationConverter(a);
if (convDef == null) {
return null;
}
return prov.converterInstance(a, convDef);
}
/*
/**********************************************************
/* Factory methods, container types:
/**********************************************************
*/
/**
* @since 2.1
*/
protected JsonSerializer<?> buildContainerSerializer(SerializerProvider prov,
JavaType type, BeanDescription beanDesc, boolean staticTyping)
throws JsonMappingException
{
final SerializationConfig config = prov.getConfig();
/* [databind#23], 15-Mar-2013, tatu: must force static handling of root value type,
* with just one important exception: if value type is "untyped", let's
* leave it as is; no clean way to make it work.
*/
if (!staticTyping && type.useStaticType()) {
if (!type.isContainerType() || type.getContentType().getRawClass() != Object.class) {
staticTyping = true;
}
}
// Let's see what we can learn about element/content/value type, type serializer for it:
JavaType elementType = type.getContentType();
TypeSerializer elementTypeSerializer = createTypeSerializer(config,
elementType);
// if elements have type serializer, can not force static typing:
if (elementTypeSerializer != null) {
staticTyping = false;
}
JsonSerializer<Object> elementValueSerializer = _findContentSerializer(prov,
beanDesc.getClassInfo());
if (type.isMapLikeType()) { // implements java.util.Map
MapLikeType
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>factoryConfig.serializerModifiers()) {
ser = mod.modifyCollectionLikeSerializer(config, clType, beanDesc, ser);
}
}
}
return ser;
}
if (type.isArrayType()) {
return buildArraySerializer(prov, (ArrayType) type, beanDesc, staticTyping,
elementTypeSerializer, elementValueSerializer);
}
return null;
}
/**
* Helper method that handles configuration details when constructing serializers for
* {@link java.util.List} types that support efficient by-index access
*
* @since 2.1
*/
protected JsonSerializer<?> buildCollectionSerializer(SerializerProvider prov,
CollectionType type, BeanDescription beanDesc, boolean staticTyping,
TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer)
throws JsonMappingException
{
SerializationConfig config = prov.getConfig();
JsonSerializer<?> ser = null;
// Order of lookups:
// 1. Custom serializers
// 2. Annotations (@JsonValue, @JsonDeserialize)
// 3. Defaults
for (Serializers serializers : customSerializers()) { // (1) Custom
ser = serializers.findCollectionSerializer(config,
type, beanDesc, elementTypeSerializer, elementValueSerializer);
if (ser != null) {
break;
}
}
if (ser == null) {
ser = findSerializerByAnnotations(prov, type, beanDesc); // (2) Annotations
if (ser == null) {
// We may also want to use serialize Collections "as beans", if (and only if)
// this is specified with `@JsonFormat(shape=Object)`
JsonFormat.Value format = beanDesc.findExpectedFormat(null);
if (format != null && format.getShape() == JsonFormat.Shape.OBJECT) {
return null;
}
Class<?> raw = type.getRawClass();
if (EnumSet.class.isAssignableFrom(raw)) {
// this may or may not be available (Class doesn't; type of field/method does)
JavaType enumType = type.getContentType();
// and even if nominally there is something, only use if it really is enum
if (!enumType.isEnumType()) {
enumType = null;
}
ser = buildEnumSetSerializer(enumType);
} else {
Class<?> elementRaw = type.getContentType().getRawClass();
if (isIndexedList(raw)) {
if (elementRaw == String.class) {
// [JACKSON-829] Must NOT use if we have custom serializer
if (elementValueSerializer == null || ClassUtil.isJacksonStdImpl(elementValueSerializer)) {
ser = IndexedStringListSerializer.instance;
}
} else
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> {
ser = buildIndexedListSerializer(type.getContentType(), staticTyping,
elementTypeSerializer, elementValueSerializer);
}
} else if (elementRaw == String.class) {
// [JACKSON-829] Must NOT use if we have custom serializer
if (elementValueSerializer == null || ClassUtil.isJacksonStdImpl(elementValueSerializer)) {
ser = StringCollectionSerializer.instance;
}
}
if (ser == null) {
ser = buildCollectionSerializer(type.getContentType(), staticTyping,
elementTypeSerializer, elementValueSerializer);
}
}
}
}
// [databind#120]: Allow post-processing
if (_factoryConfig.hasSerializerModifiers()) {
for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
ser = mod.modifyCollectionSerializer(config, type, beanDesc, ser);
}
}
return ser;
}
/*
/**********************************************************
/* Factory methods, for Collections
/**********************************************************
*/
protected boolean isIndexedList(Class<?> cls)
{
return RandomAccess.class.isAssignableFrom(cls);
}
public ContainerSerializer<?> buildIndexedListSerializer(JavaType elemType,
boolean staticTyping, TypeSerializer vts, JsonSerializer<Object> valueSerializer) {
return new IndexedListSerializer(elemType, staticTyping, vts, valueSerializer);
}
public ContainerSerializer<?> buildCollectionSerializer(JavaType elemType,
boolean staticTyping, TypeSerializer vts, JsonSerializer<Object> valueSerializer) {
return new CollectionSerializer(elemType, staticTyping, vts, valueSerializer);
}
public JsonSerializer<?> buildEnumSetSerializer(JavaType enumType) {
return new EnumSetSerializer(enumType);
}
/*
/**********************************************************
/* Factory methods, for Maps
/**********************************************************
*/
/**
* Helper method that handles configuration details when constructing serializers for
* {@link java.util.Map} types.
*/
protected JsonSerializer<?> buildMapSerializer(SerializerProvider prov,
MapType type, BeanDescription beanDesc,
boolean staticTyping, JsonSerializer<Object> keySerializer,
TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer)
throws JsonMappingException
{
final SerializationConfig config = prov.getConfig();
JsonSerializer<?> ser = null;
// Order of lookups:
// 1. Custom serializers
// 2. Annotations (@JsonValue, @JsonDeserialize)
// 3. Defaults
for (Serializers serializers : customSerializers()) { // (1) Custom
ser = serializers.findMapSerializer(config, type, beanDesc,
keySerializer, elementTypeSerializer, elementValueSerializer);
if (ser != null) { break; }
}
if (
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> /**
* Helper method that handles configuration details when constructing serializers for
* <code>Object[]</code> (and subtypes, except for String).
*/
protected JsonSerializer<?> buildArraySerializer(SerializerProvider prov,
ArrayType type, BeanDescription beanDesc,
boolean staticTyping,
TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer)
throws JsonMappingException
{
// 25-Jun-2015, tatu: Note that unlike with Collection(Like) and Map(Like) types, array
// types can not be annotated (in theory I guess we could have mix-ins but... ?)
// so we need not do primary annotation lookup here.
// So all we need is (1) Custom, (2) Default array serializers
SerializationConfig config = prov.getConfig();
JsonSerializer<?> ser = null;
for (Serializers serializers : customSerializers()) { // (1) Custom
ser = serializers.findArraySerializer(config,
type, beanDesc, elementTypeSerializer, elementValueSerializer);
if (ser != null) {
break;
}
}
if (ser == null) {
Class<?> raw = type.getRawClass();
// Important: do NOT use standard serializers if non-standard element value serializer specified
if (elementValueSerializer == null || ClassUtil.isJacksonStdImpl(elementValueSerializer)) {
if (String[].class == raw) {
ser = StringArraySerializer.instance;
} else {
// other standard types?
ser = StdArraySerializers.findStandardImpl(raw);
}
}
if (ser == null) {
ser = new ObjectArraySerializer(type.getContentType(), staticTyping, elementTypeSerializer,
elementValueSerializer);
}
}
// [databind#120]: Allow post-processing
if (_factoryConfig.hasSerializerModifiers()) {
for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
ser = mod.modifyArraySerializer(config, type, beanDesc, ser);
}
}
return ser;
}
/*
/**********************************************************
/* Factory methods, for non-container types
/**********************************************************
*/
/**
* @since 2.5
*/
protected JsonSerializer<?> buildIteratorSerializer(SerializationConfig config,
JavaType type, BeanDescription beanDesc, boolean staticTyping,
JavaType valueType)
throws JsonMappingException
{
return new IteratorSerializer(valueType, staticTyping, createTypeSerializer(config, valueType));
}
@Deprecated // since 2.5
protected JsonSerializer<?> buildIteratorSerializer(SerializationConfig config,
JavaType type, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException
{
JavaType[] params = config
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>.getTypeFactory().findTypeParameters(type, Iterator.class);
JavaType vt = (params == null || params.length != 1) ?
TypeFactory.unknownType() : params[0];
return buildIteratorSerializer(config, type, beanDesc, staticTyping, vt);
}
/**
* @since 2.5
*/
protected JsonSerializer<?> buildIterableSerializer(SerializationConfig config,
JavaType type, BeanDescription beanDesc, boolean staticTyping,
JavaType valueType)
throws JsonMappingException
{
return new IterableSerializer(valueType, staticTyping, createTypeSerializer(config, valueType));
}
@Deprecated // since 2.5
protected JsonSerializer<?> buildIterableSerializer(SerializationConfig config,
JavaType type, BeanDescription beanDesc,
boolean staticTyping)
throws JsonMappingException
{
JavaType[] params = config.getTypeFactory().findTypeParameters(type, Iterable.class);
JavaType vt = (params == null || params.length != 1) ?
TypeFactory.unknownType() : params[0];
return buildIterableSerializer(config, type, beanDesc, staticTyping, vt);
}
/**
* @since 2.5
*/
protected JsonSerializer<?> buildMapEntrySerializer(SerializationConfig config,
JavaType type, BeanDescription beanDesc, boolean staticTyping,
JavaType keyType, JavaType valueType)
throws JsonMappingException
{
return new MapEntrySerializer(valueType, keyType, valueType,
staticTyping, createTypeSerializer(config, valueType), null);
}
protected JsonSerializer<?> buildEnumSerializer(SerializationConfig config,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
/* As per [databind#24], may want to use alternate shape, serialize as JSON Object.
* Challenge here is that EnumSerializer does not know how to produce
* POJO style serialization, so we must handle that special case separately;
* otherwise pass it to EnumSerializer.
*/
JsonFormat.Value format = beanDesc.findExpectedFormat(null);
if (format != null && format.getShape() == JsonFormat.Shape.OBJECT) {
// one special case: suppress serialization of "getDeclaringClass()"...
((BasicBeanDescription) beanDesc).removeProperty("declaringClass");
// returning null will mean that eventually BeanSerializer gets constructed
return null;
}
@SuppressWarnings("unchecked")
Class<Enum<?>> enumClass = (Class<Enum<?>>) type.getRawClass();
JsonSerializer<?> ser = EnumSerializer.construct(enumClass, config, beanDesc, format);
// [Issue#120]: Allow post-processing
if (_factoryConfig.hasSerializerModifiers()) {
for (BeanSerializerModifier mod : _factory
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
/* Need to resolve? Mostly done for bean deserializers; required for
* resolving cyclic references.
*/
if (isResolvable) {
_incompleteDeserializers.put(type, deser);
((ResolvableDeserializer)deser).resolve(ctxt);
_incompleteDeserializers.remove(type);
}
if (addToCache) {
_cachedDeserializers.put(type, deser);
}
return deser;
}
/*
/**********************************************************
/* Helper methods for actual construction of deserializers
/**********************************************************
*/
/**
* Method that does the heavy lifting of checking for per-type annotations,
* find out full type, and figure out which actual factory method
* to call.
*/
@SuppressWarnings("unchecked")
protected JsonDeserializer<Object> _createDeserializer(DeserializationContext ctxt,
DeserializerFactory factory, JavaType type)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
// First things first: do we need to use abstract type mapping?
if (type.isAbstract() || type.isMapLikeType() || type.isCollectionLikeType()) {
type = factory.mapAbstractType(config, type);
}
BeanDescription beanDesc = config.introspect(type);
// Then: does type define explicit deserializer to use, with annotation(s)?
JsonDeserializer<Object> deser = findDeserializerFromAnnotation(ctxt,
beanDesc.getClassInfo());
if (deser != null) {
return deser;
}
// If not, may have further type-modification annotations to check:
JavaType newType = modifyTypeByAnnotation(ctxt, beanDesc.getClassInfo(), type);
if (newType != type) {
type = newType;
beanDesc = config.introspect(newType);
}
// We may also have a Builder type to consider...
Class<?> builder = beanDesc.findPOJOBuilder();
if (builder != null) {
return (JsonDeserializer<Object>) factory.createBuilderBasedDeserializer(
ctxt, type, beanDesc, builder);
}
// Or perhaps a Converter?
Converter<Object,Object> conv = beanDesc.findDeserializationConverter();
if (conv == null) { // nope, just construct in normal way
return (JsonDeserializer<Object>) _createDeserializer2(ctxt, factory, type, beanDesc);
}
// otherwise need to do bit of introspection
JavaType delegateType = conv.getInputType(ctxt.getTypeFactory());
// One more twist, as per [Issue#288]; probably need to get new BeanDesc
if (!delegateType.hasRawClass(type.getRawClass())) {
beanDesc = config.introspect(delegate
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>Type);
}
return new StdDelegatingDeserializer<Object>(conv, delegateType,
_createDeserializer2(ctxt, factory, delegateType, beanDesc));
}
protected JsonDeserializer<?> _createDeserializer2(DeserializationContext ctxt,
DeserializerFactory factory, JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
// If not, let's see which factory method to use:
if (type.isEnumType()) {
return factory.createEnumDeserializer(ctxt, type, beanDesc);
}
if (type.isContainerType()) {
if (type.isArrayType()) {
return factory.createArrayDeserializer(ctxt, (ArrayType) type, beanDesc);
}
if (type.isMapLikeType()) {
MapLikeType mlt = (MapLikeType) type;
if (mlt.isTrueMapType()) {
return factory.createMapDeserializer(ctxt,(MapType) mlt, beanDesc);
}
return factory.createMapLikeDeserializer(ctxt, mlt, beanDesc);
}
if (type.isCollectionLikeType()) {
/* 03-Aug-2012, tatu: As per [Issue#40], one exception is if shape
* is to be Shape.OBJECT. Ideally we'd determine it bit later on
* (to allow custom handler checks), but that won't work for other
* reasons. So do it here.
*/
JsonFormat.Value format = beanDesc.findExpectedFormat(null);
if (format == null || format.getShape() != JsonFormat.Shape.OBJECT) {
CollectionLikeType clt = (CollectionLikeType) type;
if (clt.isTrueCollectionType()) {
return factory.createCollectionDeserializer(ctxt, (CollectionType) clt, beanDesc);
}
return factory.createCollectionLikeDeserializer(ctxt, clt, beanDesc);
}
}
}
if (type.isReferenceType()) {
return factory.createReferenceDeserializer(ctxt, (ReferenceType) type, beanDesc);
}
if (JsonNode.class.isAssignableFrom(type.getRawClass())) {
return factory.createTreeDeserializer(config, type, beanDesc);
}
return factory.createBeanDeserializer(ctxt, type, beanDesc);
}
/**
* Helper method called to check if a class or method
* has annotation that tells which class to use for deserialization.
* Returns null if no such annotation found.
*/
protected JsonDeserializer<Object> findDeserializerFromAnnotation(DeserializationContext ctxt,
Annotated ann)
throws JsonMappingException
{
Object deserDef = ctxt.getAnnotationIntrospector().findDeserializer(ann
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> JsonSerializer or Class<JsonSerializer> instead");
}
Class<?> cls = (Class<?>) src;
if (cls == noneClass || ClassUtil.isBogusClass(cls)) {
return null;
}
return cls;
}
/*
/**********************************************************
/* Overridable error reporting methods
/**********************************************************
*/
// NOTE: changed 2.6 -> 2.7 to pass context; no way to make backwards compatible
protected JsonDeserializer<Object> _handleUnknownValueDeserializer(DeserializationContext ctxt, JavaType type)
throws JsonMappingException
{
/* Let's try to figure out the reason, to give better error
* messages
*/
Class<?> rawClass = type.getRawClass();
if (!ClassUtil.isConcrete(rawClass)) {
throw JsonMappingException.from(ctxt, "Can not find a Value deserializer for abstract type "+type);
}
throw JsonMappingException.from(ctxt, "Can not find a Value deserializer for type "+type);
}
protected KeyDeserializer _handleUnknownKeyDeserializer(DeserializationContext ctxt, JavaType type)
throws JsonMappingException
{
throw JsonMappingException.from(ctxt, "Can not find a (Map) Key deserializer for type "+type);
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>();
MapSerializer ser = new MapSerializer(this, property, keySerializer, valueSerializer, ignored);
if (sortKeys != ser._sortKeys) {
ser = new MapSerializer(ser, _filterId, sortKeys);
}
return ser;
}
@Override
public MapSerializer withFilterId(Object filterId) {
if (_filterId == filterId) {
return this;
}
_ensureOverride();
return new MapSerializer(this, filterId, _sortKeys);
}
/**
* Mutant factory for constructing an instance with different inclusion strategy
* for content (Map values).
*
* @since 2.5
*/
public MapSerializer withContentInclusion(Object suppressableValue) {
if (suppressableValue == _suppressableValue) {
return this;
}
_ensureOverride();
return new MapSerializer(this, _valueTypeSerializer, suppressableValue);
}
/**
* @since 2.3
*/
public static MapSerializer construct(String[] ignoredList, JavaType mapType,
boolean staticValueType, TypeSerializer vts,
JsonSerializer<Object> keySerializer, JsonSerializer<Object> valueSerializer,
Object filterId)
{
HashSet<String> ignoredEntries = (ignoredList == null || ignoredList.length == 0)
? null : ArrayBuilders.arrayToSet(ignoredList);
JavaType keyType, valueType;
if (mapType == null) {
keyType = valueType = UNSPECIFIED_TYPE;
} else {
keyType = mapType.getKeyType();
valueType = mapType.getContentType();
}
// If value type is final, it's same as forcing static value typing:
if (!staticValueType) {
staticValueType = (valueType != null && valueType.isFinal());
} else {
// also: Object.class can not be handled as static, ever
if (valueType.getRawClass() == Object.class) {
staticValueType = false;
}
}
MapSerializer ser = new MapSerializer(ignoredEntries, keyType, valueType, staticValueType, vts,
keySerializer, valueSerializer);
if (filterId != null) {
ser = ser.withFilterId(filterId);
}
return ser;
}
/*
/**********************************************************
/* Post-processing (contextualization)
/**********************************************************
*/
@Override
public JsonSerializer<?> createContextual(SerializerProvider provider,
BeanProperty property)
throws JsonMappingException
{
/* 29-Sep-2012, tatu: Actually, we need to do much more contextual
* checking here since we finally know for sure the property,
* and it may have
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>(cc);
if (serializer == null) {
if (_valueType.hasGenericTypes()) {
serializer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_valueType, cc), provider);
} else {
serializer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicValueSerializers;
}
}
try {
serializer.serialize(valueElem, gen, provider);
} catch (Exception e) {
// Add reference information
String keyDesc = ""+keyElem;
wrapAndThrow(provider, e, value, keyDesc);
}
}
}
/**
* Serialization method called when exclusion filtering needs to be applied.
*/
public void serializeOptionalFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider,
Object suppressableValue)
throws IOException
{
// If value type needs polymorphic type handling, some more work needed:
if (_valueTypeSerializer != null) {
serializeTypedFields(value, gen, provider, suppressableValue);
return;
}
final HashSet<String> ignored = _ignoredEntries;
PropertySerializerMap serializers = _dynamicValueSerializers;
for (Map.Entry<?,?> entry : value.entrySet()) {
// First find key serializer
final Object keyElem = entry.getKey();
JsonSerializer<Object> keySerializer;
if (keyElem == null) {
keySerializer = provider.findNullKeySerializer(_keyType, _property);
} else {
if (ignored != null && ignored.contains(keyElem)) continue;
keySerializer = _keySerializer;
}
// Then value serializer
final Object valueElem = entry.getValue();
JsonSerializer<Object> valueSer;
if (valueElem == null) {
if (suppressableValue != null) { // all suppressions include null-suppression
continue;
}
valueSer = provider.getDefaultNullValueSerializer();
} else {
valueSer = _valueSerializer;
if (valueSer == null) {
Class<?> cc = valueElem.getClass();
valueSer = serializers.serializerFor(cc);
if (valueSer == null) {
if (_valueType.hasGenericTypes()) {
valueSer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_valueType, cc), provider);
} else {
valueSer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicValueSerializers;
}
}
// also may need to skip non-empty values:
if ((suppressableValue == JsonInclude.Include.NON_EMPTY)
&& valueSer.isEmpty(provider, valueElem)) {
continue;
}
}
// and then serialize, if all went well
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>Serializer;
}
// or by value; nulls often suppressed
final Object valueElem = entry.getValue();
JsonSerializer<Object> valueSer;
// And then value
if (valueElem == null) {
if (suppressableValue != null) { // all suppressions include null-suppression
continue;
}
valueSer = provider.getDefaultNullValueSerializer();
} else {
valueSer = _valueSerializer;
if (valueSer == null) {
Class<?> cc = valueElem.getClass();
valueSer = serializers.serializerFor(cc);
if (valueSer == null) {
if (_valueType.hasGenericTypes()) {
valueSer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_valueType, cc), provider);
} else {
valueSer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicValueSerializers;
}
}
// also may need to skip non-empty values:
if ((suppressableValue == JsonInclude.Include.NON_EMPTY)
&& valueSer.isEmpty(provider, valueElem)) {
continue;
}
}
// and with that, ask filter to handle it
prop.reset(keyElem, keySerializer, valueSer);
try {
filter.serializeAsField(valueElem, gen, provider, prop);
} catch (Exception e) {
String keyDesc = ""+keyElem;
wrapAndThrow(provider, e, value, keyDesc);
}
}
}
@Deprecated // since 2.5
public void serializeFilteredFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider,
PropertyFilter filter) throws IOException {
serializeFilteredFields(value, gen, provider, filter,
provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES) ? null : JsonInclude.Include.NON_NULL);
}
/**
* @since 2.5
*/
public void serializeTypedFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider,
Object suppressableValue) // since 2.5
throws IOException
{
final HashSet<String> ignored = _ignoredEntries;
PropertySerializerMap serializers = _dynamicValueSerializers;
for (Map.Entry<?,?> entry : value.entrySet()) {
Object keyElem = entry.getKey();
JsonSerializer<Object> keySerializer;
if (keyElem == null) {
keySerializer = provider.findNullKeySerializer(_keyType, _property);
} else {
// One twist: is entry ignorable? If so, skip
if (ignored != null && ignored.contains(keyElem)) continue;
keySerializer = _keySerializer;
}
final Object valueElem = entry.getValue
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>();
// And then value
JsonSerializer<Object> valueSer;
if (valueElem == null) {
if (suppressableValue != null) { // all suppression include null suppression
continue;
}
valueSer = provider.getDefaultNullValueSerializer();
} else {
valueSer = _valueSerializer;
Class<?> cc = valueElem.getClass();
valueSer = serializers.serializerFor(cc);
if (valueSer == null) {
if (_valueType.hasGenericTypes()) {
valueSer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_valueType, cc), provider);
} else {
valueSer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicValueSerializers;
}
// also may need to skip non-empty values:
if ((suppressableValue == JsonInclude.Include.NON_EMPTY)
&& valueSer.isEmpty(provider, valueElem)) {
continue;
}
}
keySerializer.serialize(keyElem, gen, provider);
try {
valueSer.serializeWithType(valueElem, gen, provider, _valueTypeSerializer);
} catch (Exception e) {
String keyDesc = ""+keyElem;
wrapAndThrow(provider, e, value, keyDesc);
}
}
}
@Deprecated // since 2.5
protected void serializeTypedFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider)
throws IOException {
serializeTypedFields(value, gen, provider,
provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES) ? null : JsonInclude.Include.NON_NULL);
}
/*
/**********************************************************
/* Schema related functionality
/**********************************************************
*/
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
{
ObjectNode o = createSchemaNode("object", true);
//(ryan) even though it's possible to statically determine the "value" type of the map,
// there's no way to statically determine the keys, so the "Entries" can't be determined.
return o;
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
JsonMapFormatVisitor v2 = (visitor == null) ? null : visitor.expectMapFormat(typeHint);
if (v2 != null) {
v2.keyFormat(_keySerializer, _keyType);
JsonSerializer<?> valueSer = _valueSerializer;
if (valueSer == null) {
valueSer = _findAndAddDynamic(_dynamicValueSerializers,
_valueType, visitor.getProvider());
}
v2.valueFormat(valueSer, _valueType);
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.JsonParser.NumberType;
import com.fasterxml.jackson.core.io.NumberInput;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.Converter;
/**
* Base class for common deserializers. Contains shared
* base functionality for dealing with primitive values, such
* as (re)parsing from String.
*/
public abstract class StdDeserializer<T>
extends JsonDeserializer<T>
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
/**
* Bitmask that covers {@link DeserializationFeature#USE_BIG_INTEGER_FOR_INTS}
* and {@link DeserializationFeature#USE_LONG_FOR_INTS}, used for more efficient
* cheks when coercing integral values for untyped deserialization.
*
* @since 2.6
*/
protected final static int F_MASK_INT_COERCIONS =
DeserializationFeature.USE_BIG_INTEGER_FOR_INTS.getMask()
| DeserializationFeature.USE_LONG_FOR_INTS.getMask();
/**
* Type of values this deserializer handles: sometimes
* exact types, other time most specific supertype of
* types deserializer handles (which may be as generic
* as {@link Object} in some case)
*/
final protected Class<?> _valueClass;
protected StdDeserializer(Class<?> vc) {
_valueClass = vc;
}
protected StdDeserializer(JavaType valueType) {
_valueClass = (valueType == null) ? null : valueType.getRawClass();
}
/**
* Copy-constructor for sub-classes to use, most often when creating
* new instances for {@link com.fasterxml.jackson.databind.deser.ContextualDeserializer}.
*
* @since 2.5
*/
protected StdDeserializer(StdDeserializer<?> src) {
_valueClass = src._valueClass;
}
/*
/**********************************************************
/* Accessors
/**********************************************************
*/
@Override
public Class<?> handledType() { return _valueClass; }
/*
/**********************************************************
/* Extended API
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>.getCurrentToken();
if (t == JsonToken.END_ARRAY) {
break;
}
// Ok: no need to convert Strings, but must recognize nulls
value = (t == JsonToken.VALUE_NULL) ? deser.getNullValue(ctxt) : deser.deserialize(p, ctxt);
} else {
value = deser.deserialize(p, ctxt);
}
result.add(value);
}
return result;
}
@Override
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
// In future could check current token... for now this should be enough:
return typeDeserializer.deserializeTypedFromArray(p, ctxt);
}
/**
* Helper method called when current token is not START_ARRAY. Will either
* throw an exception, or try to handle value as if member of implicit
* array, depending on configuration.
*/
private final Collection<String> handleNonArray(JsonParser p, DeserializationContext ctxt, Collection<String> result) throws IOException
{
// implicit arrays from single values?
boolean canWrap = (_unwrapSingle == Boolean.TRUE) ||
((_unwrapSingle == null) &&
ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY));
if (!canWrap) {
throw ctxt.mappingException(_collectionType.getRawClass());
}
// Strings are one of "native" (intrinsic) types, so there's never type deserializer involved
JsonDeserializer<String> valueDes = _valueDeserializer;
JsonToken t = p.getCurrentToken();
String value;
if (t == JsonToken.VALUE_NULL) {
value = (valueDes == null) ? null : valueDes.getNullValue(ctxt);
} else {
value = (valueDes == null) ? _parseString(p, ctxt) : valueDes.deserialize(p, ctxt);
}
result.add(value);
return result;
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> a "real"
* Collection type; meaning whether it represents a parameterized subtype of
* {@link java.util.Collection} or just something that acts like one.
*/
public boolean isTrueMapType() {
return Map.class.isAssignableFrom(_class);
}
/*
* /********************************************************** /* Standard
* methods /**********************************************************
*/
@Override
public String toString() {
return "[map-like type; class " + _class.getName() + ", " + _keyType
+ " -> " + _valueType + "]";
}
@Override
public boolean equals(Object o) {
if (o == this)
return true;
if (o == null)
return false;
if (o.getClass() != getClass())
return false;
MapLikeType other = (MapLikeType) o;
return (_class == other._class) && _keyType.equals(other._keyType)
&& _valueType.equals(other._valueType);
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.type;
import java.lang.reflect.Array;
import com.fasterxml.jackson.databind.JavaType;
/**
* Array types represent Java arrays, both primitive and object valued.
* Further, Object-valued arrays can have element type of any other
* legal {@link JavaType}.
*/
public final class ArrayType
extends TypeBase
{
private static final long serialVersionUID = 1L;
/**
* Type of elements in the array.
*/
protected final JavaType _componentType;
/**
* We will also keep track of shareable instance of empty array,
* since it usually needs to be constructed any way; and because
* it is essentially immutable and thus can be shared.
*/
protected final Object _emptyArray;
protected ArrayType(JavaType componentType, TypeBindings bindings, Object emptyInstance,
Object valueHandler, Object typeHandler, boolean asStatic)
{
// No super-class, interfaces, for now
super(emptyInstance.getClass(), bindings, null, null,
componentType.hashCode(),
valueHandler, typeHandler, asStatic);
_componentType = componentType;
_emptyArray = emptyInstance;
}
public static ArrayType construct(JavaType componentType, TypeBindings bindings) {
return construct(componentType, bindings, null, null);
}
public static ArrayType construct(JavaType componentType, TypeBindings bindings,
Object valueHandler, Object typeHandler) {
// Figuring out raw class for generic array is actually bit tricky...
Object emptyInstance = Array.newInstance(componentType.getRawClass(), 0);
return new ArrayType(componentType, bindings, emptyInstance, valueHandler, typeHandler, false);
}
@Override
public JavaType withContentType(JavaType contentType) {
Object emptyInstance = Array.newInstance(contentType.getRawClass(), 0);
return new ArrayType(contentType, _bindings, emptyInstance,
_valueHandler, _typeHandler, _asStatic);
}
@Override
public ArrayType withTypeHandler(Object h)
{
if (h == _typeHandler) {
return this;
}
return new ArrayType(_componentType, _bindings, _emptyArray, _valueHandler, h, _asStatic);
}
@Override
public ArrayType withContentTypeHandler(Object h)
{
if (h == _componentType.<Object>getTypeHandler()) {
return this;
}
return new ArrayType(_componentType.withTypeHandler(h), _bindings, _emptyArray,
_valueHandler, _typeHandler, _asStatic);
}
@Override
public ArrayType withValueHandler(Object h) {
if (h == _
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>" aka runtime typing):
* meaning that no runtime information is needed for determining serializers to use.
* The main use case is to allow forcing of specific root value serialization type,
* and specifically in resolving serializers for contained types (element types
* for arrays, Collections and Maps).
*
* @since 2.2
*/
public abstract JavaType withStaticTyping();
/*
/**********************************************************
/* Type coercion fluent factory methods
/**********************************************************
*/
/**
* Mutant factory method that will try to create and return a sub-type instance
* for known parameterized types; for other types will return `null` to indicate
* that no just refinement makes necessary sense, without trying to detect
* special status through implemented interfaces.
*
* @since 2.7
*/
public abstract JavaType refine(Class<?> rawType, TypeBindings bindings,
JavaType superClass, JavaType[] superInterfaces);
/**
* Legacy method used for forcing sub-typing of this type into
* type specified by specific type erasure.
* Deprecated as of 2.7 as such specializations really ought to
* go through {@link TypeFactory}, not directly via {@link JavaType}.
*
* @since 2.7
*/
@Deprecated
public JavaType forcedNarrowBy(Class<?> subclass)
{
if (subclass == _class) { // can still optimize for simple case
return this;
}
JavaType result = _narrow(subclass);
// TODO: these checks should NOT actually be needed; above should suffice:
if (_valueHandler != result.<Object>getValueHandler()) {
result = result.withValueHandler(_valueHandler);
}
if (_typeHandler != result.<Object>getTypeHandler()) {
result = result.withTypeHandler(_typeHandler);
}
return result;
}
@Deprecated // since 2.7
protected abstract JavaType _narrow(Class<?> subclass);
/*
/**********************************************************
/* Implementation of ResolvedType API
/**********************************************************
*/
@Override
public final Class<?> getRawClass() { return _class; }
/**
* Method that can be used to check whether this type has
* specified Class as its type erasure. Put another way, returns
* true if instantiation of this Type is given (type-erased) Class.
*/
@Override
public final boolean hasRawClass(Class<?> clz) { return _class == clz; }
/**
* @since 2.6
*/
public final boolean isTypeOrSubTypeOf(Class<?> clz) {
return (_class == clz) || (clz.isAssignableFrom(_class));
}
@Override
public boolean isAbstract() {
return Modifier.
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>isAbstract(_class.getModifiers());
}
/**
* Convenience method for checking whether underlying Java type
* is a concrete class or not: abstract classes and interfaces
* are not.
*/
@Override
public boolean isConcrete() {
int mod = _class.getModifiers();
if ((mod & (Modifier.INTERFACE | Modifier.ABSTRACT)) == 0) {
return true;
}
/* 19-Feb-2010, tatus: Holy mackarel; primitive types
* have 'abstract' flag set...
*/
return _class.isPrimitive();
}
@Override
public boolean isThrowable() { return Throwable.class.isAssignableFrom(_class); }
@Override
public boolean isArrayType() { return false; }
@Override
public final boolean isEnumType() { return _class.isEnum(); }
@Override
public final boolean isInterface() { return _class.isInterface(); }
@Override
public final boolean isPrimitive() { return _class.isPrimitive(); }
@Override
public final boolean isFinal() { return Modifier.isFinal(_class.getModifiers()); }
/**
* @return True if type represented is a container type; this includes
* array, Map and Collection types.
*/
@Override
public abstract boolean isContainerType();
/**
* @return True if type is either true {@link java.util.Collection} type,
* or something similar (meaning it has at least one type parameter,
* which describes type of contents)
*/
@Override
public boolean isCollectionLikeType() { return false; }
/**
* @return True if type is either true {@link java.util.Map} type,
* or something similar (meaning it has at least two type parameter;
* first one describing key type, second value type)
*/
@Override
public boolean isMapLikeType() { return false; }
/**
* Convenience method, short-hand for
*<code>
* getRawClass() == Object.class
*</code>
* and used to figure if we basically have "untyped" type object.
*
* @since 2.5
*/
public final boolean isJavaLangObject() { return _class == Object.class; }
/**
* Accessor for checking whether handlers for dealing with values of
* this type should use static typing (as opposed to dynamic typing).
* Note that while value of 'true' does mean that static typing is to
* be used, value of 'false' may still be overridden by other settings.
*
* @since 2.2
*/
public final boolean useStaticType() { return _asStatic; }
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>);
/*
/**********************************************************
/* Generic attributes (2.3+)
/**********************************************************
*/
/**
* Method for accessing attributes available in this context.
* Per-call attributes have highest precedence; attributes set
* via {@link ObjectReader} or {@link ObjectWriter} have lower
* precedence.
*
* @param key Key of the attribute to get
* @return Value of the attribute, if any; null otherwise
*
* @since 2.3
*/
public abstract Object getAttribute(Object key);
/**
* Method for setting per-call value of given attribute.
* This will override any previously defined value for the
* attribute within this context.
*
* @param key Key of the attribute to set
* @param value Value to set attribute to
*
* @return This context object, to allow chaining
*
* @since 2.3
*/
public abstract DatabindContext setAttribute(Object key, Object value);
/*
/**********************************************************
/* Type instantiation/resolution
/**********************************************************
*/
/**
* Convenience method for constructing {@link JavaType} for given JDK
* type (usually {@link java.lang.Class})
*/
public JavaType constructType(Type type) {
return getTypeFactory().constructType(type);
}
/**
* Convenience method for constructing subtypes, retaining generic
* type parameter (if any)
*/
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
// simple optimization to avoid costly introspection if type-erased type does NOT differ
if (baseType.getRawClass() == subclass) {
return baseType;
}
return getConfig().constructSpecializedType(baseType, subclass);
}
public abstract TypeFactory getTypeFactory();
/*
/**********************************************************
/* Helper object construction
/**********************************************************
*/
public ObjectIdGenerator<?> objectIdGeneratorInstance(Annotated annotated,
ObjectIdInfo objectIdInfo)
throws JsonMappingException
{
Class<?> implClass = objectIdInfo.getGeneratorType();
final MapperConfig<?> config = getConfig();
HandlerInstantiator hi = config.getHandlerInstantiator();
ObjectIdGenerator<?> gen = (hi == null) ? null : hi.objectIdGeneratorInstance(config, annotated, implClass);
if (gen == null) {
gen = (ObjectIdGenerator<?>) ClassUtil.createInstance(implClass,
config.canOverrideAccessModifiers());
}
return gen.forScope(objectIdInfo.getScope());
}
public ObjectIdResolver objectIdResolverInstance(Annotated annotated, ObjectIdInfo objectIdInfo)
{
Class<? extends ObjectIdResolver> implClass = objectIdInfo.getResolverType();
final MapperConfig<?> config = getConfig();
HandlerInstanti
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>ator hi = config.getHandlerInstantiator();
ObjectIdResolver resolver = (hi == null) ? null : hi.resolverIdGeneratorInstance(config, annotated, implClass);
if (resolver == null) {
resolver = ClassUtil.createInstance(implClass, config.canOverrideAccessModifiers());
}
return resolver;
}
/**
* Helper method to use to construct a {@link Converter}, given a definition
* that may be either actual converter instance, or Class for instantiating one.
*
* @since 2.2
*/
@SuppressWarnings("unchecked")
public Converter<Object,Object> converterInstance(Annotated annotated,
Object converterDef)
throws JsonMappingException
{
if (converterDef == null) {
return null;
}
if (converterDef instanceof Converter<?,?>) {
return (Converter<Object,Object>) converterDef;
}
if (!(converterDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned Converter definition of type "
+converterDef.getClass().getName()+"; expected type Converter or Class<Converter> instead");
}
Class<?> converterClass = (Class<?>)converterDef;
// there are some known "no class" markers to consider too:
if (converterClass == Converter.None.class || ClassUtil.isBogusClass(converterClass)) {
return null;
}
if (!Converter.class.isAssignableFrom(converterClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "
+converterClass.getName()+"; expected Class<Converter>");
}
final MapperConfig<?> config = getConfig();
HandlerInstantiator hi = config.getHandlerInstantiator();
Converter<?,?> conv = (hi == null) ? null : hi.converterInstance(config, annotated, converterClass);
if (conv == null) {
conv = (Converter<?,?>) ClassUtil.createInstance(converterClass,
config.canOverrideAccessModifiers());
}
return (Converter<Object,Object>) conv;
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>package com.fasterxml.jackson.databind;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.type.TypeBindings;
import com.fasterxml.jackson.databind.util.Annotations;
import com.fasterxml.jackson.databind.util.Converter;
/**
* Basic container for information gathered by {@link ClassIntrospector} to
* help in constructing serializers and deserializers.
* Note that the main implementation type is
* {@link com.fasterxml.jackson.databind.introspect.BasicBeanDescription},
* meaning that it is safe to upcast to this type.
*/
public abstract class BeanDescription
{
/*
/**********************************************************
/* Configuration
/**********************************************************
*/
/**
* Bean type information, including raw class and possible
* * generics information
*/
protected final JavaType _type;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
protected BeanDescription(JavaType type) {
_type = type;
}
/*
/**********************************************************
/* Simple accesors
/**********************************************************
*/
/**
* Method for accessing declared type of bean being introspected,
* including full generic type information (from declaration)
*/
public JavaType getType() { return _type; }
public Class<?> getBeanClass() { return _type.getRawClass(); }
/**
* Method for accessing low-level information about Class this
* item describes.
*/
public abstract AnnotatedClass getClassInfo();
/**
* Accessor for getting information about Object Id expected to
* be used for this POJO type, if any.
*/
public abstract ObjectIdInfo getObjectIdInfo();
/**
* Method for checking whether class being described has any
* annotations recognized by registered annotation introspector.
*/
public abstract boolean hasKnownClassAnnotations();
/**
* Accessor for type bindings that may be needed to fully resolve
* types of member object, such as return and argument types of
* methods and constructors, and types of fields.
*
* @deprecated Since 2.7, use {@link #resolveType(java.lang.reflect.Type)} instead.
*/
@Deprecated
public abstract TypeBindings bindingsForBeanType();
/**
* Method for resolving given JDK type, using this bean as the
* generic type resolution context.
*/
public abstract JavaType resolveType(java.lang.reflect.Type j
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>cc);
if (serializer == null) {
// To fix [JACKSON-508]
if (_elementType.hasGenericTypes()) {
serializer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_elementType, cc), provider);
} else {
serializer = _findAndAddDynamic(serializers, cc, provider);
}
}
serializer.serialize(elem, gen, provider);
}
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
// [JACKSON-55] Need to add reference information
/* 05-Mar-2009, tatu: But one nasty edge is when we get
* StackOverflow: usually due to infinite loop. But that gets
* hidden within an InvocationTargetException...
*/
Throwable t = e;
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
if (t instanceof Error) {
throw (Error) t;
}
throw JsonMappingException.wrapWithPath(t, elem, i);
}
}
public void serializeContentsUsing(Object[] value, JsonGenerator jgen, SerializerProvider provider,
JsonSerializer<Object> ser) throws IOException
{
final int len = value.length;
final TypeSerializer typeSer = _valueTypeSerializer;
int i = 0;
Object elem = null;
try {
for (; i < len; ++i) {
elem = value[i];
if (elem == null) {
provider.defaultSerializeNull(jgen);
continue;
}
if (typeSer == null) {
ser.serialize(elem, jgen, provider);
} else {
ser.serializeWithType(elem, jgen, provider, typeSer);
}
}
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
Throwable t = e;
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
if (t instanceof Error) {
throw (Error) t;
}
throw JsonMappingException.wrapWithPath(t, elem, i);
}
}
public void serializeTypedContents(Object[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException
{
final int len = value.length;
final TypeSerializer typeSer = _valueTypeSerializer;
int i = 0;
Object elem = null;
try {
PropertySerializerMap serializers = _dynamicSerializers;
for (; i < len; ++i) {
elem = value[i];
if (elem == null) {
provider.default
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>SerializeNull(jgen);
continue;
}
Class<?> cc = elem.getClass();
JsonSerializer<Object> serializer = serializers.serializerFor(cc);
if (serializer == null) {
serializer = _findAndAddDynamic(serializers, cc, provider);
}
serializer.serializeWithType(elem, jgen, provider, typeSer);
}
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
Throwable t = e;
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
if (t instanceof Error) {
throw (Error) t;
}
throw JsonMappingException.wrapWithPath(t, elem, i);
}
}
@SuppressWarnings("deprecation")
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
throws JsonMappingException
{
ObjectNode o = createSchemaNode("array", true);
if (typeHint != null) {
JavaType javaType = provider.constructType(typeHint);
if (javaType.isArrayType()) {
Class<?> componentType = ((ArrayType) javaType).getContentType().getRawClass();
// 15-Oct-2010, tatu: We can't serialize plain Object.class; but what should it produce here? Untyped?
if (componentType == Object.class) {
o.set("items", com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode());
} else {
JsonSerializer<Object> ser = provider.findValueSerializer(componentType, _property);
JsonNode schemaNode = (ser instanceof SchemaAware) ?
((SchemaAware) ser).getSchema(provider, null) :
com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode();
o.set("items", schemaNode);
}
}
}
return o;
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
JsonArrayFormatVisitor arrayVisitor = visitor.expectArrayFormat(typeHint);
if (arrayVisitor != null) {
TypeFactory tf = visitor.getProvider().getTypeFactory();
JavaType contentType = tf.moreSpecificType(_elementType, typeHint.getContentType());
if (contentType == null) {
throw JsonMappingException.from(visitor.getProvider(), "Could not resolve type");
}
JsonSerializer<?> valueSer = _elementSerializer;
if (valueSer == null) {
valueSer = visitor.getProvider().findValueSerializer(contentType, _property);
}
arrayVisitor.itemsFormat(valueSer, contentType);
}
}
protected
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> visitor;
}
}, this.getType());
} else {
super.depositSchemaProperty(visitor, provider);
}
}
// Override needed to support legacy JSON Schema generator
@Override
protected void _depositSchemaProperty(ObjectNode propertiesNode, JsonNode schemaNode)
{
JsonNode props = schemaNode.get("properties");
if (props != null) {
Iterator<Entry<String, JsonNode>> it = props.fields();
while (it.hasNext()) {
Entry<String,JsonNode> entry = it.next();
String name = entry.getKey();
if (_nameTransformer != null) {
name = _nameTransformer.transform(name);
}
propertiesNode.set(name, entry.getValue());
}
}
}
/*
/**********************************************************
/* Overrides: internal, other
/**********************************************************
*/
// need to override as we must get unwrapping instance...
@Override
protected JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
Class<?> type, SerializerProvider provider) throws JsonMappingException
{
JsonSerializer<Object> serializer;
if (_nonTrivialBaseType != null) {
JavaType subtype = provider.constructSpecializedType(_nonTrivialBaseType, type);
serializer = provider.findValueSerializer(subtype, this);
} else {
serializer = provider.findValueSerializer(type, this);
}
NameTransformer t = _nameTransformer;
if (serializer.isUnwrappingSerializer()) {
t = NameTransformer.chainedTransformer(t, ((UnwrappingBeanSerializer) serializer)._nameTransformer);
}
serializer = serializer.unwrappingSerializer(t);
_dynamicSerializers = _dynamicSerializers.newWith(type, serializer);
return serializer;
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
public boolean useForType(JavaType t)
{
switch (_appliesFor) {
case NON_CONCRETE_AND_ARRAYS:
while (t.isArrayType()) {
t = t.getContentType();
}
// fall through
case OBJECT_AND_NON_CONCRETE:
// 19-Apr-2016, tatu: ReferenceType like Optional also requires similar handling:
while (t.isReferenceType()) {
t = t.getReferencedType();
}
return t.isJavaLangObject()
|| (!t.isConcrete()
// [databind#88] Should not apply to JSON tree models:
&& !TreeNode.class.isAssignableFrom(t.getRawClass()));
case NON_FINAL:
while (t.isArrayType()) {
t = t.getContentType();
}
// 19-Apr-2016, tatu: ReferenceType like Optional also requires similar handling:
while (t.isReferenceType()) {
t = t.getReferencedType();
}
// [databind#88] Should not apply to JSON tree models:
return !t.isFinal() && !TreeNode.class.isAssignableFrom(t.getRawClass());
default:
//case JAVA_LANG_OBJECT:
return t.isJavaLangObject();
}
}
}
/*
/**********************************************************
/* Internal constants, singletons
/**********************************************************
*/
// Quick little shortcut, to avoid having to use global TypeFactory instance...
// 19-Oct-2015, tatu: Not sure if this is really safe to do; let's at least allow
// some amount of introspection
private final static JavaType JSON_NODE_TYPE =
SimpleType.constructUnsafe(JsonNode.class);
// TypeFactory.defaultInstance().constructType(JsonNode.class);
// 16-May-2009, tatu: Ditto ^^^
protected final static AnnotationIntrospector DEFAULT_ANNOTATION_INTROSPECTOR = new JacksonAnnotationIntrospector();
protected final static VisibilityChecker<?> STD_VISIBILITY_CHECKER = VisibilityChecker.Std.defaultInstance();
/**
* @deprecated Since 2.6, do not use: will be removed in 2.7 or later
*/
@Deprecated
protected final static PrettyPrinter _defaultPrettyPrinter = new DefaultPrettyPrinter();
/**
* Base settings contain defaults used for all {@link ObjectMapper}
* instances.
*/
protected final static BaseSettings DEFAULT_BASE = new BaseSettings(
null, // can not share global ClassIntrospector any more (2.5+)
DEFAULT_ANNOTATION_INTROSPECTOR,
STD_VISIBILITY_CHECK
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
* package)
*/
@Override
public ArrayNode createArrayNode() {
return _deserializationConfig.getNodeFactory().arrayNode();
}
/**
* Method for constructing a {@link JsonParser} out of JSON tree
* representation.
*
* @param n Root node of the tree that resulting parser will read from
*/
@Override
public JsonParser treeAsTokens(TreeNode n) {
return new TreeTraversingParser((JsonNode) n, this);
}
/**
* Convenience conversion method that will bind data given JSON tree
* contains into specific value (usually bean) type.
*<p>
* Functionally equivalent to:
*<pre>
* objectMapper.convertValue(n, valueClass);
*</pre>
*/
@SuppressWarnings("unchecked")
@Override
public <T> T treeToValue(TreeNode n, Class<T> valueType)
throws JsonProcessingException
{
try {
// Simple cast when we just want to cast to, say, ObjectNode
// ... one caveat; while everything is Object.class, let's not take shortcut
if (valueType != Object.class && valueType.isAssignableFrom(n.getClass())) {
return (T) n;
}
// 20-Apr-2016, tatu: Another thing: for VALUE_EMBEDDED_OBJECT, assume similar
// short-cut coercion
if (n.asToken() == JsonToken.VALUE_EMBEDDED_OBJECT) {
if (n instanceof POJONode) {
Object ob = ((POJONode) n).getPojo();
if ((ob == null) || valueType.isInstance(ob)) {
return (T) ob;
}
}
}
return readValue(treeAsTokens(n), valueType);
} catch (JsonProcessingException e) {
throw e;
} catch (IOException e) { // should not occur, no real i/o...
throw new IllegalArgumentException(e.getMessage(), e);
}
}
/**
* Reverse of {@link #treeToValue}; given a value (usually bean), will
* construct equivalent JSON Tree representation. Functionally similar
* to serializing value into JSON and parsing JSON as tree, but
* more efficient.
*<p>
* NOTE: while results are usually identical to that of serialization followed
* by deserialization, this is not always the case. In some cases serialization
* into intermediate representation will retain encapsulation of things like
* raw value ({@link com.fasterxml.jackson.databind.util.RawValue}) or basic
* node identity ({@link JsonNode}). If so, result is a valid tree, but values
* are not re-construct
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> * functionality threw
*/
@SuppressWarnings("unchecked")
public <T> T convertValue(Object fromValue, Class<T> toValueType)
throws IllegalArgumentException
{
// sanity check for null first:
if (fromValue == null) return null;
return (T) _convert(fromValue, _typeFactory.constructType(toValueType));
}
/**
* See {@link #convertValue(Object, Class)}
*/
@SuppressWarnings("unchecked")
public <T> T convertValue(Object fromValue, TypeReference<?> toValueTypeRef)
throws IllegalArgumentException
{
return (T) convertValue(fromValue, _typeFactory.constructType(toValueTypeRef));
}
/**
* See {@link #convertValue(Object, Class)}
*/
@SuppressWarnings("unchecked")
public <T> T convertValue(Object fromValue, JavaType toValueType)
throws IllegalArgumentException
{
// sanity check for null first:
if (fromValue == null) return null;
return (T) _convert(fromValue, toValueType);
}
/**
* Actual conversion implementation: instead of using existing read
* and write methods, much of code is inlined. Reason for this is
* that we must avoid root value wrapping/unwrapping both for efficiency and
* for correctness. If root value wrapping/unwrapping is actually desired,
* caller must use explicit <code>writeValue</code> and
* <code>readValue</code> methods.
*/
@SuppressWarnings("resource")
protected Object _convert(Object fromValue, JavaType toValueType)
throws IllegalArgumentException
{
// also, as per [databind#11], consider case for simple cast
/* But with caveats: one is that while everything is Object.class, we don't
* want to "optimize" that out; and the other is that we also do not want
* to lose conversions of generic types.
*/
Class<?> targetType = toValueType.getRawClass();
if (targetType != Object.class
&& !toValueType.hasGenericTypes()
&& targetType.isAssignableFrom(fromValue.getClass())) {
return fromValue;
}
// Then use TokenBuffer, which is a JsonGenerator:
TokenBuffer buf = new TokenBuffer(this, false);
if (isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
buf = buf.forceUseOfBigDecimal(true);
}
try {
// inlined 'writeValue' with minor changes:
// first: disable wrapping when writing
SerializationConfig config = getSerializationConfig().without(SerializationFeature.WRAP_ROOT_VALUE);
// no need to check for closing of TokenBuffer
_serializerProvider(config).serializeValue(buf, fromValue);
// then
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>: as per [databind#840], let's only consider
* `true` to have any significance.
*/
if ((order != null) && order.alphabetic()) {
return Boolean.TRUE;
}
return null;
}
@Override
public void findAndAddVirtualProperties(MapperConfig<?> config, AnnotatedClass ac,
List<BeanPropertyWriter> properties) {
JsonAppend ann = _findAnnotation(ac, JsonAppend.class);
if (ann == null) {
return;
}
final boolean prepend = ann.prepend();
JavaType propType = null;
// First: any attribute-backed properties?
JsonAppend.Attr[] attrs = ann.attrs();
for (int i = 0, len = attrs.length; i < len; ++i) {
if (propType == null) {
propType = config.constructType(Object.class);
}
BeanPropertyWriter bpw = _constructVirtualProperty(attrs[i],
config, ac, propType);
if (prepend) {
properties.add(i, bpw);
} else {
properties.add(bpw);
}
}
// Then: general-purpose virtual properties?
JsonAppend.Prop[] props = ann.props();
for (int i = 0, len = props.length; i < len; ++i) {
BeanPropertyWriter bpw = _constructVirtualProperty(props[i],
config, ac);
if (prepend) {
properties.add(i, bpw);
} else {
properties.add(bpw);
}
}
}
protected BeanPropertyWriter _constructVirtualProperty(JsonAppend.Attr attr,
MapperConfig<?> config, AnnotatedClass ac, JavaType type)
{
PropertyMetadata metadata = attr.required() ?
PropertyMetadata.STD_REQUIRED : PropertyMetadata.STD_OPTIONAL;
// could add Index, Description in future, if those matter
String attrName = attr.value();
// allow explicit renaming; if none, default to attribute name
PropertyName propName = _propertyName(attr.propName(), attr.propNamespace());
if (!propName.hasSimpleName()) {
propName = PropertyName.construct(attrName);
}
// now, then, we need a placeholder for member (no real Field/Method):
AnnotatedMember member = new VirtualAnnotatedMember(ac, ac.getRawType(),
attrName, type.getRawClass());
// and with that and property definition
SimpleBeanPropertyDefinition propDef = SimpleBeanPropertyDefinition.construct(config,
member, propName, metadata, attr.include());
// can construct the property writer
return AttributePropertyWriter.construct(attrName,
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> propDef,
ac.getAnnotations(), type);
}
protected BeanPropertyWriter _constructVirtualProperty(JsonAppend.Prop prop,
MapperConfig<?> config, AnnotatedClass ac)
{
PropertyMetadata metadata = prop.required() ?
PropertyMetadata.STD_REQUIRED : PropertyMetadata.STD_OPTIONAL;
PropertyName propName = _propertyName(prop.name(), prop.namespace());
JavaType type = config.constructType(prop.type());
// now, then, we need a placeholder for member (no real Field/Method):
AnnotatedMember member = new VirtualAnnotatedMember(ac, ac.getRawType(),
propName.getSimpleName(), type.getRawClass());
// and with that and property definition
SimpleBeanPropertyDefinition propDef = SimpleBeanPropertyDefinition.construct(config,
member, propName, metadata, prop.include());
Class<?> implClass = prop.value();
HandlerInstantiator hi = config.getHandlerInstantiator();
VirtualBeanPropertyWriter bpw = (hi == null) ? null
: hi.virtualPropertyWriterInstance(config, implClass);
if (bpw == null) {
bpw = (VirtualBeanPropertyWriter) ClassUtil.createInstance(implClass,
config.canOverrideAccessModifiers());
}
// one more thing: give it necessary contextual information
return bpw.withConfig(config, ac, propDef, type);
}
/*
/**********************************************************
/* Serialization: property annotations
/**********************************************************
*/
@Override
public PropertyName findNameForSerialization(Annotated a)
{
JsonGetter jg = _findAnnotation(a, JsonGetter.class);
if (jg != null) {
return PropertyName.construct(jg.value());
}
JsonProperty pann = _findAnnotation(a, JsonProperty.class);
if (pann != null) {
return PropertyName.construct(pann.value());
}
if (_hasOneOf(a, ANNOTATIONS_TO_INFER_SER)) {
return PropertyName.USE_DEFAULT;
}
return null;
}
@Override
public boolean hasAsValueAnnotation(AnnotatedMethod am) {
JsonValue ann = _findAnnotation(am, JsonValue.class);
// value of 'false' means disabled...
return (ann != null && ann.value());
}
/*
/**********************************************************
/* Deserialization: general annotations
/**********************************************************
*/
@Override
public Object findDeserializer(Annotated a)
{
JsonDeserialize ann = _findAnnotation(a, JsonDeserialize.class);
if (ann != null) {
@SuppressWarnings("rawtypes")
Class<? extends JsonDeserializer> deserClass = ann.using();
if (deserClass != JsonDeserializer.None
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> getSerializer() { return _serializer; }
public JavaType getSerializationType() { return _cfgSerializationType; }
public Class<?> getRawSerializationType() {
return (_cfgSerializationType == null) ? null : _cfgSerializationType.getRawClass();
}
/*
public JavaType getFullPropertyType() {
if (_accessorMethod != null) {
return _accessorMethod.getType()
}
if (_field != null) {
return _field.getType();
}
return null;
}
*/
/**
* @deprecated Since 2.7, to be removed from 2.8, use {@link #getType()} instead.
*/
@Deprecated
public Class<?> getPropertyType() {
if (_accessorMethod != null) {
return _accessorMethod.getReturnType();
}
if (_field != null) {
return _field.getType();
}
return null;
}
/**
* Get the generic property type of this property writer.
*
* @return The property type, or null if not found.
*
* @deprecated Since 2.7, to be removed from 2.8, use {@link #getType()} instead.
*/
@Deprecated
public Type getGenericPropertyType() {
if (_accessorMethod != null) {
return _accessorMethod.getGenericReturnType();
}
if (_field != null) {
return _field.getGenericType();
}
return null;
}
public Class<?>[] getViews() { return _includeInViews; }
/*
/**********************************************************
/* PropertyWriter methods (serialization)
/**********************************************************
*/
/**
* Method called to access property that this bean stands for, from
* within given bean, and to serialize it as a JSON Object field
* using appropriate serializer.
*/
@Override
public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
{
// inlined 'get()'
final Object value = (_accessorMethod == null) ? _field.get(bean) : _accessorMethod.invoke(bean);
// Null handling is bit different, check that first
if (value == null) {
if (_nullSerializer != null) {
gen.writeFieldName(_name);
_nullSerializer.serialize(null, gen, prov);
}
return;
}
// then find serializer to use
JsonSerializer<Object> ser = _serializer;
if (ser == null) {
Class<?> cls = value.getClass();
PropertySerializerMap m = _dynamicSerializers;
ser = m.serializerFor(cls);
if (ser == null) {
ser = _findAndAddDynamic(m, cls, prov);
}
}
// and then see if we must suppress certain values
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> tabular output
serializeAsPlaceholder(bean, gen, prov);
return;
}
} else if (_suppressableValue.equals(value)) { // can NOT suppress entries in tabular output
serializeAsPlaceholder(bean, gen, prov);
return;
}
}
// For non-nulls: simple check for direct cycles
if (value == bean) {
if (_handleSelfReference(bean, gen, prov, ser)) {
return;
}
}
if (_typeSerializer == null) {
ser.serialize(value, gen, prov);
} else {
ser.serializeWithType(value, gen, prov, _typeSerializer);
}
}
/**
* Method called to serialize a placeholder used in tabular output when
* real value is not to be included (is filtered out), but when we need
* an entry so that field indexes will not be off. Typically this should
* output null or empty String, depending on datatype.
*
* @since 2.1
*/
@Override
public void serializeAsPlaceholder(Object bean, JsonGenerator gen, SerializerProvider prov)
throws Exception
{
if (_nullSerializer != null) {
_nullSerializer.serialize(null, gen, prov);
} else {
gen.writeNull();
}
}
/*
/**********************************************************
/* PropertyWriter methods (schema generation)
/**********************************************************
*/
// Also part of BeanProperty implementation
@Override
public void depositSchemaProperty(JsonObjectFormatVisitor v,
SerializerProvider provider)
throws JsonMappingException
{
if (v != null) {
if (isRequired()) {
v.property(this);
} else {
v.optionalProperty(this);
}
}
}
// // // Legacy support for JsonFormatVisitable
/**
* Attempt to add the output of the given {@link BeanPropertyWriter} in the given {@link ObjectNode}.
* Otherwise, add the default schema {@link JsonNode} in place of the writer's output
*
* @param propertiesNode Node which the given property would exist within
* @param provider Provider that can be used for accessing dynamic aspects of serialization
* processing
*/
@Override
@Deprecated
public void depositSchemaProperty(ObjectNode propertiesNode, SerializerProvider provider)
throws JsonMappingException
{
JavaType propType = getSerializationType();
// 03-Dec-2010, tatu: SchemaAware REALLY should use JavaType, but alas it doesn't...
Type hint = (propType == null) ? getType() : propType.getRawClass();
JsonNode schemaNode;
// Maybe it already has annotated/statically configured serializer?
JsonSerializer<Object> ser = getSerializer();
if (ser == null
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>) { // nope
ser = provider.findValueSerializer(getType(), this);
}
boolean isOptional = !isRequired();
if (ser instanceof SchemaAware) {
schemaNode = ((SchemaAware) ser).getSchema(provider, hint, isOptional) ;
} else {
schemaNode = com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode();
}
_depositSchemaProperty(propertiesNode, schemaNode);
}
/*
/**********************************************************
/* Helper methods
/**********************************************************
*/
protected JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
Class<?> type, SerializerProvider provider) throws JsonMappingException
{
PropertySerializerMap.SerializerAndMapResult result;
if (_nonTrivialBaseType != null) {
JavaType t = provider.constructSpecializedType(_nonTrivialBaseType, type);
result = map.findAndAddPrimarySerializer(t, provider, this);
} else {
result = map.findAndAddPrimarySerializer(type, provider, this);
}
// did we get a new map of serializers? If so, start using it
if (map != result.map) {
_dynamicSerializers = result.map;
}
return result.serializer;
}
/**
* Method that can be used to access value of the property this
* Object describes, from given bean instance.
*<p>
* Note: method is final as it should not need to be overridden -- rather,
* calling method(s) ({@link #serializeAsField}) should be overridden
* to change the behavior
*/
public final Object get(Object bean) throws Exception {
return (_accessorMethod == null) ? _field.get(bean) : _accessorMethod.invoke(bean);
}
/**
* Method called to handle a direct self-reference through this property.
* Method can choose to indicate an error by throwing {@link JsonMappingException};
* fully handle serialization (and return true); or indicate that it should be
* serialized normally (return false).
*<p>
* Default implementation will throw {@link JsonMappingException} if
* {@link SerializationFeature#FAIL_ON_SELF_REFERENCES} is enabled;
* or return <code>false</code> if it is disabled.
*
* @return True if method fully handled self-referential value; false if not (caller
* is to handle it) or {@link JsonMappingException} if there is no way handle it
*/
protected boolean _handleSelfReference(Object bean, JsonGenerator gen, SerializerProvider prov, JsonSerializer<?> ser)
throws JsonMappingException {
if (prov.isEnabled(SerializationFeature.FAIL_ON_SELF_REFERENCES)
&& !
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>.Iterable}.
*<p>
* Note: sub-classes may choose to complete replace implementation,
* if they want to alter priority of serializer lookups.
*/
@Override
@SuppressWarnings("unchecked")
public JsonSerializer<Object> createSerializer(SerializerProvider prov,
JavaType origType)
throws JsonMappingException
{
// Very first thing, let's check if there is explicit serializer annotation:
final SerializationConfig config = prov.getConfig();
BeanDescription beanDesc = config.introspect(origType);
JsonSerializer<?> ser = findSerializerFromAnnotation(prov, beanDesc.getClassInfo());
if (ser != null) {
return (JsonSerializer<Object>) ser;
}
boolean staticTyping;
// Next: we may have annotations that further indicate actual type to use (a super type)
final AnnotationIntrospector intr = config.getAnnotationIntrospector();
JavaType type = (intr == null) ? origType
: intr.refineSerializationType(config, beanDesc.getClassInfo(), origType);
if (type == origType) { // no changes, won't force static typing
staticTyping = false;
} else { // changes; assume static typing; plus, need to re-introspect if class differs
staticTyping = true;
if (!type.hasRawClass(origType.getRawClass())) {
beanDesc = config.introspect(type);
}
}
// Slight detour: do we have a Converter to consider?
Converter<Object,Object> conv = beanDesc.findSerializationConverter();
if (conv == null) { // no, simple
return (JsonSerializer<Object>) _createSerializer2(prov, type, beanDesc, staticTyping);
}
JavaType delegateType = conv.getOutputType(prov.getTypeFactory());
// One more twist, as per [databind#288]; probably need to get new BeanDesc
if (!delegateType.hasRawClass(type.getRawClass())) {
beanDesc = config.introspect(delegateType);
// [#359]: explicitly check (again) for @JsonSerializer...
ser = findSerializerFromAnnotation(prov, beanDesc.getClassInfo());
}
// [databind#731]: Should skip if nominally java.lang.Object
if (ser == null && !delegateType.isJavaLangObject()) {
ser = _createSerializer2(prov, delegateType, beanDesc, true);
}
return new StdDelegatingSerializer(conv, delegateType, ser);
}
protected JsonSerializer<?> _createSerializer2(SerializerProvider prov,
JavaType type, BeanDescription beanDesc, boolean staticTyping)
throws JsonMappingException
{
JsonSerializer<?> ser = null;
final SerializationConfig config = prov.
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
}
}
}
if (ser != null) {
// [databind#120]: Allow post-processing
if (_factoryConfig.hasSerializerModifiers()) {
for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
ser = mod.modifySerializer(config, beanDesc, ser);
}
}
}
return ser;
}
/*
/**********************************************************
/* Other public methods that are not part of
/* JsonSerializerFactory API
/**********************************************************
*/
/**
* Method that will try to construct a {@link BeanSerializer} for
* given class. Returns null if no properties are found.
*/
public JsonSerializer<Object> findBeanSerializer(SerializerProvider prov, JavaType type,
BeanDescription beanDesc)
throws JsonMappingException
{
// First things first: we know some types are not beans...
if (!isPotentialBeanType(type.getRawClass())) {
// 03-Aug-2012, tatu: Except we do need to allow serializers for Enums,
// as per [databind#24]
if (!type.isEnumType()) {
return null;
}
}
return constructBeanSerializer(prov, beanDesc);
}
/**
* @since 2.7
*/
public JsonSerializer<?> findReferenceSerializer(SerializerProvider prov, ReferenceType refType,
BeanDescription beanDesc, boolean staticTyping)
throws JsonMappingException
{
JavaType contentType = refType.getContentType();
TypeSerializer contentTypeSerializer = contentType.getTypeHandler();
final SerializationConfig config = prov.getConfig();
if (contentTypeSerializer == null) {
contentTypeSerializer = createTypeSerializer(config, contentType);
}
JsonSerializer<Object> contentSerializer = contentType.getValueHandler();
for (Serializers serializers : customSerializers()) {
JsonSerializer<?> ser = serializers.findReferenceSerializer(config, refType, beanDesc,
contentTypeSerializer, contentSerializer);
if (ser != null) {
return ser;
}
}
if (refType.isTypeOrSubTypeOf(AtomicReference.class)) {
return new AtomicReferenceSerializer(refType, staticTyping,
contentTypeSerializer, contentSerializer);
}
return null;
}
/**
* Method called to create a type information serializer for values of given
* non-container property
* if one is needed. If not needed (no polymorphic handling configured), should
* return null.
*
* @param baseType Declared type to use as the base type for type information serializer
*
* @return Type serializer to use for property values, if one is needed; null if not.
*/
public TypeSerializer findPropertyTypeSerializer(JavaType baseType,
SerializationConfig config, AnnotatedMember accessor)
throws
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> */
protected AnnotationMap _classAnnotations;
/**
* Flag to indicate whether creator information has been resolved
* or not.
*/
protected boolean _creatorsResolved = false;
/**
* Default constructor of the annotated class, if it has one.
*/
protected AnnotatedConstructor _defaultConstructor;
/**
* Single argument constructors the class has, if any.
*/
protected List<AnnotatedConstructor> _constructors;
/**
* Single argument static methods that might be usable
* as factory methods
*/
protected List<AnnotatedMethod> _creatorMethods;
/**
* Member methods of interest; for now ones with 0 or 1 arguments
* (just optimization, since others won't be used now)
*/
protected AnnotatedMethodMap _memberMethods;
/**
* Member fields of interest: ones that are either public,
* or have at least one annotation.
*/
protected List<AnnotatedField> _fields;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
/**
* Constructor will not do any initializations, to allow for
* configuring instances differently depending on use cases
*/
private AnnotatedClass(JavaType type, Class<?> rawType, TypeBindings bindings,
List<JavaType> superTypes,
AnnotationIntrospector aintr, MixInResolver mir, TypeFactory tf,
AnnotationMap classAnnotations)
{
_type = type;
_class = rawType;
_bindings = bindings;
_superTypes = superTypes;
_annotationIntrospector = aintr;
_typeFactory = tf;
_mixInResolver = mir;
_primaryMixIn = (_mixInResolver == null) ? null
: _mixInResolver.findMixInClassFor(_class);
_classAnnotations = classAnnotations;
}
@Override
public AnnotatedClass withAnnotations(AnnotationMap ann) {
return new AnnotatedClass(_type, _class, _bindings, _superTypes,
_annotationIntrospector, _mixInResolver, _typeFactory, ann);
}
/**
* Factory method that instantiates an instance. Returned instance
* will only be initialized with class annotations, but not with
* any method information.
*
* @since 2.7
*/
public static AnnotatedClass construct(JavaType type, MapperConfig<?> config) {
AnnotationIntrospector intr = config.isAnnotationProcessingEnabled()
? config.getAnnotationIntrospector() : null;
Class<?> raw = type.getRawClass();
return new AnnotatedClass(type, raw, type.getBindings(),
ClassUtil.findSuperTypes(type, null, false), intr,
(MixInResolver) config, config.getTypeFactory(), null);
}
/**
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
* @since 2.7
*/
public static AnnotatedClass construct(JavaType type, MapperConfig<?> config,
MixInResolver mir)
{
AnnotationIntrospector intr = config.isAnnotationProcessingEnabled()
? config.getAnnotationIntrospector() : null;
Class<?> raw = type.getRawClass();
return new AnnotatedClass(type, raw, type.getBindings(),
ClassUtil.findSuperTypes(type, null, false),
intr, mir, config.getTypeFactory(), null);
}
/**
* Method similar to {@link #construct}, but that will NOT include
* information from supertypes; only class itself and any direct
* mix-ins it may have.
*/
public static AnnotatedClass constructWithoutSuperTypes(Class<?> cls, MapperConfig<?> config)
{
if (config == null) {
return new AnnotatedClass(null, cls, TypeBindings.emptyBindings(),
Collections.<JavaType>emptyList(), null, null, null, null);
}
AnnotationIntrospector intr = config.isAnnotationProcessingEnabled()
? config.getAnnotationIntrospector() : null;
return new AnnotatedClass(null, cls, TypeBindings.emptyBindings(),
Collections.<JavaType>emptyList(), intr, (MixInResolver) config, config.getTypeFactory(), null);
}
public static AnnotatedClass constructWithoutSuperTypes(Class<?> cls, MapperConfig<?> config,
MixInResolver mir)
{
if (config == null) {
return new AnnotatedClass(null, cls, TypeBindings.emptyBindings(),
Collections.<JavaType>emptyList(), null, null, null, null);
}
AnnotationIntrospector intr = config.isAnnotationProcessingEnabled()
? config.getAnnotationIntrospector() : null;
return new AnnotatedClass(null, cls, TypeBindings.emptyBindings(),
Collections.<JavaType>emptyList(), intr, mir, config.getTypeFactory(), null);
}
/*
/**********************************************************
/* TypeResolutionContext implementation
/**********************************************************
*/
@Override
public JavaType resolveType(Type type) {
return _typeFactory.constructType(type, _bindings);
}
/*
/**********************************************************
/* Annotated impl
/**********************************************************
*/
@Override
public Class<?> getAnnotated() { return _class; }
@Override
public int getModifiers() { return _class.getModifiers(); }
@Override
public String getName() { return _class.getName(); }
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return _classAnnotations().get(acls);
}
@Override
public boolean hasAnnotation(Class<?> acls) {
return _classAnnotations().has
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> class annotations are needed
synchronized (this) {
anns = _classAnnotations;
if (anns == null) {
anns = _resolveClassAnnotations();
_classAnnotations = anns;
}
}
}
return anns;
}
/**
* Initialization method that will recursively collect Jackson
* annotations for this class and all super classes and
* interfaces.
*/
private AnnotationMap _resolveClassAnnotations()
{
AnnotationMap ca = new AnnotationMap();
// Should skip processing if annotation processing disabled
if (_annotationIntrospector != null) {
// add mix-in annotations first (overrides)
if (_primaryMixIn != null) {
_addClassMixIns(ca, _class, _primaryMixIn);
}
// first, annotations from the class itself:
_addAnnotationsIfNotPresent(ca,
ClassUtil.findClassAnnotations(_class));
// and then from super types
for (JavaType type : _superTypes) {
// and mix mix-in annotations in-between
_addClassMixIns(ca, type);
_addAnnotationsIfNotPresent(ca,
ClassUtil.findClassAnnotations(type.getRawClass()));
}
/* and finally... any annotations there might be for plain
* old Object.class: separate because for all other purposes
* it is just ignored (not included in super types)
*/
/* 12-Jul-2009, tatu: Should this be done for interfaces too?
* For now, yes, seems useful for some cases, and not harmful for any?
*/
_addClassMixIns(ca, Object.class);
}
return ca;
}
/**
* Initialization method that will find out all constructors
* and potential static factory methods the class has.
*/
private void resolveCreators()
{
// Then see which constructors we have
List<AnnotatedConstructor> constructors = null;
ClassUtil.Ctor[] declaredCtors = ClassUtil.getConstructors(_class);
// Constructor also always members of this class
TypeResolutionContext typeContext = this;
// 30-Apr-2016, tatu: [databind#1215]: Actually, while true, this does
// NOT apply to context since sub-class may have type bindings
// TypeResolutionContext typeContext = new TypeResolutionContext.Basic(_typeFactory, _type.getBindings());
for (ClassUtil.Ctor ctor : declaredCtors) {
if (_isIncludableConstructor(ctor.getConstructor())) {
if (ctor.getParamCount() == 0) {
_defaultConstructor = _constructDefaultConstructor(ctor, typeContext);
} else {
if (constructors == null) {
constructors = new
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> * @param methodFilter Filter used to determine which methods to include
*/
private void resolveMemberMethods()
{
_memberMethods = new AnnotatedMethodMap();
AnnotatedMethodMap mixins = new AnnotatedMethodMap();
// first: methods from the class itself
_addMemberMethods(_class, this, _memberMethods, _primaryMixIn, mixins);
// and then augment these with annotations from super-types:
for (JavaType type : _superTypes) {
Class<?> mixin = (_mixInResolver == null) ? null : _mixInResolver.findMixInClassFor(type.getRawClass());
_addMemberMethods(type.getRawClass(),
new TypeResolutionContext.Basic(_typeFactory, type.getBindings()),
_memberMethods, mixin, mixins);
}
// Special case: mix-ins for Object.class? (to apply to ALL classes)
if (_mixInResolver != null) {
Class<?> mixin = _mixInResolver.findMixInClassFor(Object.class);
if (mixin != null) {
_addMethodMixIns(_class, _memberMethods, mixin, mixins);
}
}
/* Any unmatched mix-ins? Most likely error cases (not matching
* any method); but there is one possible real use case:
* exposing Object#hashCode (alas, Object#getClass can NOT be
* exposed)
*/
// 14-Feb-2011, tatu: AnnotationIntrospector is null if annotations not enabled; if so, can skip:
if (_annotationIntrospector != null) {
if (!mixins.isEmpty()) {
Iterator<AnnotatedMethod> it = mixins.iterator();
while (it.hasNext()) {
AnnotatedMethod mixIn = it.next();
try {
Method m = Object.class.getDeclaredMethod(mixIn.getName(), mixIn.getRawParameterTypes());
if (m != null) {
// Since it's from java.lang.Object, no generics, no need for real type context:
AnnotatedMethod am = _constructMethod(m, this);
_addMixOvers(mixIn.getAnnotated(), am, false);
_memberMethods.add(am);
}
} catch (Exception e) { }
}
}
}
}
/**
* Method that will collect all member (non-static) fields
* that are either public, or have at least a single annotation
* associated with them.
*/
private void resolveFields()
{
Map<String,AnnotatedField> foundFields = _findFields(_type, this, null);
if (foundFields == null || foundFields.size() == 0) {
_fields = Collections.emptyList();
} else
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> {
_fields = new ArrayList<AnnotatedField>(foundFields.size());
_fields.addAll(foundFields.values());
}
}
/*
/**********************************************************
/* Helper methods for resolving class annotations
/* (resolution consisting of inheritance, overrides,
/* and injection of mix-ins as necessary)
/**********************************************************
*/
/**
* Helper method for adding any mix-in annotations specified
* class might have.
*/
protected void _addClassMixIns(AnnotationMap annotations, JavaType target)
{
if (_mixInResolver != null) {
final Class<?> toMask = target.getRawClass();
_addClassMixIns(annotations, toMask, _mixInResolver.findMixInClassFor(toMask));
}
}
protected void _addClassMixIns(AnnotationMap annotations, Class<?> target)
{
if (_mixInResolver != null) {
_addClassMixIns(annotations, target, _mixInResolver.findMixInClassFor(target));
}
}
protected void _addClassMixIns(AnnotationMap annotations, Class<?> toMask,
Class<?> mixin)
{
if (mixin == null) {
return;
}
// Ok, first: annotations from mix-in class itself:
_addAnnotationsIfNotPresent(annotations, ClassUtil.findClassAnnotations(mixin));
/* And then from its supertypes, if any. But note that we will
* only consider super-types up until reaching the masked
* class (if found); this because often mix-in class
* is a sub-class (for convenience reasons). And if so, we
* absolutely must NOT include super types of masked class,
* as that would inverse precedence of annotations.
*/
for (Class<?> parent : ClassUtil.findSuperClasses(mixin, toMask, false)) {
_addAnnotationsIfNotPresent(annotations, ClassUtil.findClassAnnotations(parent));
}
}
/*
/**********************************************************
/* Helper methods for populating creator (ctor, factory) information
/**********************************************************
*/
protected void _addConstructorMixIns(Class<?> mixin)
{
MemberKey[] ctorKeys = null;
int ctorCount = (_constructors == null) ? 0 : _constructors.size();
for (ClassUtil.Ctor ctor0 : ClassUtil.getConstructors(mixin)) {
Constructor<?> ctor = ctor0.getConstructor();
if (ctor.getParameterTypes().length == 0) {
if (_defaultConstructor != null) {
_addMixOvers(ctor, _defaultConstructor, false);
}
} else {
if (ctorKeys == null) {
ctorKeys = new MemberKey[ctorCount];
for (int i = 0; i < ctorCount; ++
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>,
TypeResolutionContext typeContext, Map<String,AnnotatedField> fields)
{
/* First, a quick test: we only care for regular classes (not
* interfaces, primitive types etc), except for Object.class.
* A simple check to rule out other cases is to see if there
* is a super class or not.
*/
JavaType parent = type.getSuperClass();
if (parent != null) {
final Class<?> cls = type.getRawClass();
// Let's add super-class' fields first, then ours.
/* 21-Feb-2010, tatu: Need to handle masking: as per [JACKSON-226]
* we otherwise get into trouble...
*/
fields = _findFields(parent,
new TypeResolutionContext.Basic(_typeFactory, parent.getBindings()),
fields);
for (Field f : ClassUtil.getDeclaredFields(cls)) {
// static fields not included (transients are at this point, filtered out later)
if (!_isIncludableField(f)) {
continue;
}
/* Ok now: we can (and need) not filter out ignorable fields
* at this point; partly because mix-ins haven't been
* added, and partly because logic can be done when
* determining get/settability of the field.
*/
if (fields == null) {
fields = new LinkedHashMap<String,AnnotatedField>();
}
fields.put(f.getName(), _constructField(f, typeContext));
}
// And then... any mix-in overrides?
if (_mixInResolver != null) {
Class<?> mixin = _mixInResolver.findMixInClassFor(cls);
if (mixin != null) {
_addFieldMixIns(mixin, cls, fields);
}
}
}
return fields;
}
/**
* Method called to add field mix-ins from given mix-in class (and its fields)
* into already collected actual fields (from introspected classes and their
* super-classes)
*/
protected void _addFieldMixIns(Class<?> mixInCls, Class<?> targetClass,
Map<String,AnnotatedField> fields)
{
List<Class<?>> parents = ClassUtil.findSuperClasses(mixInCls, targetClass, true);
for (Class<?> mixin : parents) {
for (Field mixinField : ClassUtil.getDeclaredFields(mixin)) {
// there are some dummy things (static, synthetic); better ignore
if (!_isIncludableField(mixinField)) {
continue;
}
String name = mixinField.getName();
// anything to mask? (if not, quietly ignore)
Annotated
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> */
@Override
public boolean hasGetter() { return _getters != null; }
@Override
public boolean hasSetter() { return _setters != null; }
@Override
public boolean hasField() { return _fields != null; }
@Override
public boolean hasConstructorParameter() { return _ctorParameters != null; }
@Override
public boolean couldDeserialize() {
return (_ctorParameters != null) || (_setters != null) || (_fields != null);
}
@Override
public boolean couldSerialize() {
return (_getters != null) || (_fields != null);
}
@Override
public AnnotatedMethod getGetter()
{
// Easy with zero or one getters...
Linked<AnnotatedMethod> curr = _getters;
if (curr == null) {
return null;
}
Linked<AnnotatedMethod> next = curr.next;
if (next == null) {
return curr.value;
}
// But if multiple, verify that they do not conflict...
for (; next != null; next = next.next) {
/* [JACKSON-255] Allow masking, i.e. do not report exception if one
* is in super-class from the other
*/
Class<?> currClass = curr.value.getDeclaringClass();
Class<?> nextClass = next.value.getDeclaringClass();
if (currClass != nextClass) {
if (currClass.isAssignableFrom(nextClass)) { // next is more specific
curr = next;
continue;
}
if (nextClass.isAssignableFrom(currClass)) { // current more specific
continue;
}
}
/* 30-May-2014, tatu: Three levels of precedence:
*
* 1. Regular getters ("getX")
* 2. Is-getters ("isX")
* 3. Implicit, possible getters ("x")
*/
int priNext = _getterPriority(next.value);
int priCurr = _getterPriority(curr.value);
if (priNext != priCurr) {
if (priNext < priCurr) {
curr = next;
}
continue;
}
throw new IllegalArgumentException("Conflicting getter definitions for property \""+getName()+"\": "
+curr.value.getFullName()+" vs "+next.value.getFullName());
}
// One more thing; to avoid having to do it again...
_getters = curr.withoutNext();
return curr.value;
}
@Override
public AnnotatedMethod getSetter()
{
// Easy with zero or one getters...
Linked<AnnotatedMethod> curr = _setters;
if (curr == null) {
return null;
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> }
Linked<AnnotatedMethod> next = curr.next;
if (next == null) {
return curr.value;
}
// But if multiple, verify that they do not conflict...
for (; next != null; next = next.next) {
// Allow masking, i.e. do not fail if one is in super-class from the other
Class<?> currClass = curr.value.getDeclaringClass();
Class<?> nextClass = next.value.getDeclaringClass();
if (currClass != nextClass) {
if (currClass.isAssignableFrom(nextClass)) { // next is more specific
curr = next;
continue;
}
if (nextClass.isAssignableFrom(currClass)) { // current more specific
continue;
}
}
AnnotatedMethod nextM = next.value;
AnnotatedMethod currM = curr.value;
/* 30-May-2014, tatu: Two levels of precedence:
*
* 1. Regular setters ("setX(...)")
* 2. Implicit, possible setters ("x(...)")
*/
int priNext = _setterPriority(nextM);
int priCurr = _setterPriority(currM);
if (priNext != priCurr) {
if (priNext < priCurr) {
curr = next;
}
continue;
}
// 11-Dec-2015, tatu: As per [databind#1033] allow pluggable conflict resolution
if (_annotationIntrospector != null) {
AnnotatedMethod pref = _annotationIntrospector.resolveSetterConflict(_config,
currM, nextM);
// note: should be one of nextM/currM; but no need to check
if (pref == currM) {
continue;
}
if (pref == nextM) {
curr = next;
continue;
}
}
throw new IllegalArgumentException("Conflicting setter definitions for property \""+getName()+"\": "
+curr.value.getFullName()+" vs "+next.value.getFullName());
}
// One more thing; to avoid having to do it again...
_setters = curr.withoutNext();
return curr.value;
}
@Override
public AnnotatedField getField()
{
if (_fields == null) {
return null;
}
// If multiple, verify that they do not conflict...
AnnotatedField field = _fields.value;
Linked<AnnotatedField> next = _fields.next;
for (; next != null; next = next.next) {
AnnotatedField nextField = next.value;
Class<?> fieldClass = field.getDeclaringClass();
Class<?> nextClass = next
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>Field.getDeclaringClass();
if (fieldClass != nextClass) {
if (fieldClass.isAssignableFrom(nextClass)) { // next is more specific
field = nextField;
continue;
}
if (nextClass.isAssignableFrom(fieldClass)) { // getter more specific
continue;
}
}
throw new IllegalArgumentException("Multiple fields representing property \""+getName()+"\": "
+field.getFullName()+" vs "+nextField.getFullName());
}
return field;
}
@Override
public AnnotatedParameter getConstructorParameter()
{
if (_ctorParameters == null) {
return null;
}
/* Hmmh. Checking for constructor parameters is trickier; for one,
* we must allow creator and factory method annotations.
* If this is the case, constructor parameter has the precedence.
*
* So, for now, just try finding the first constructor parameter;
* if none, first factory method. And don't check for dups, if we must,
* can start checking for them later on.
*/
Linked<AnnotatedParameter> curr = _ctorParameters;
do {
if (curr.value.getOwner() instanceof AnnotatedConstructor) {
return curr.value;
}
curr = curr.next;
} while (curr != null);
return _ctorParameters.value;
}
@Override
public Iterator<AnnotatedParameter> getConstructorParameters() {
if (_ctorParameters == null) {
return ClassUtil.emptyIterator();
}
return new MemberIterator<AnnotatedParameter>(_ctorParameters);
}
@Override
public AnnotatedMember getAccessor()
{
AnnotatedMember m = getGetter();
if (m == null) {
m = getField();
}
return m;
}
@Override
public AnnotatedMember getMutator()
{
AnnotatedMember m = getConstructorParameter();
if (m == null) {
m = getSetter();
if (m == null) {
m = getField();
}
}
return m;
}
@Override
public AnnotatedMember getNonConstructorMutator() {
AnnotatedMember m = getSetter();
if (m == null) {
m = getField();
}
return m;
}
@Override
public AnnotatedMember getPrimaryMember() {
if (_forSerialization) {
return getAccessor();
}
return getMutator();
}
protected int _getterPriority(AnnotatedMethod m)
{
final String name = m.getName();
// [databind#238]: Also, regular getters have precedence over "is-getters"
if (name.startsWith("get") && name.length() > 3) {
// should we check capitalization?
return
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> if (valueElem == null) {
provider.defaultSerializeNull(jgen);
} else {
Class<?> cc = valueElem.getClass();
JsonSerializer<Object> ser = serializers.serializerFor(cc);
if (ser == null) {
if (_valueType.hasGenericTypes()) {
ser = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_valueType, cc), provider);
} else {
ser = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicValueSerializers;
}
try {
if (vts == null) {
ser.serialize(valueElem, jgen, provider);
} else {
ser.serializeWithType(valueElem, jgen, provider, vts);
}
} catch (Exception e) {
// [JACKSON-55] Need to add reference information
String keyDesc = ""+keyElem;
wrapAndThrow(provider, e, value, keyDesc);
}
}
}
/**
* Method called to serialize fields, when the value type is statically known,
* so that value serializer is passed and does not need to be fetched from
* provider.
*/
protected void serializeUsing(Map.Entry<?, ?> value, JsonGenerator jgen, SerializerProvider provider,
JsonSerializer<Object> ser)
throws IOException, JsonGenerationException
{
final JsonSerializer<Object> keySerializer = _keySerializer;
final TypeSerializer vts = _valueTypeSerializer;
final boolean skipNulls = !provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES);
Object valueElem = value.getValue();
Object keyElem = value.getKey();
if (keyElem == null) {
provider.findNullKeySerializer(_keyType, _property).serialize(null, jgen, provider);
} else {
// [JACKSON-314] also may need to skip entries with null values
if (skipNulls && valueElem == null) return;
keySerializer.serialize(keyElem, jgen, provider);
}
if (valueElem == null) {
provider.defaultSerializeNull(jgen);
} else {
try {
if (vts == null) {
ser.serialize(valueElem, jgen, provider);
} else {
ser.serializeWithType(valueElem, jgen, provider, vts);
}
} catch (Exception e) {
// [JACKSON-55] Need to add reference information
String keyDesc = ""+keyElem;
wrapAndThrow(provider, e, value, keyDesc);
}
}
}
/*
/**********************************************************
/* Internal helper methods
/**********************************************************
*/
protected final JsonSerializer<
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
}
@Override
public void serializeContents(List<?> value, JsonGenerator jgen, SerializerProvider provider)
throws IOException
{
if (_elementSerializer != null) {
serializeContentsUsing(value, jgen, provider, _elementSerializer);
return;
}
if (_valueTypeSerializer != null) {
serializeTypedContents(value, jgen, provider);
return;
}
final int len = value.size();
if (len == 0) {
return;
}
int i = 0;
try {
PropertySerializerMap serializers = _dynamicSerializers;
for (; i < len; ++i) {
Object elem = value.get(i);
if (elem == null) {
provider.defaultSerializeNull(jgen);
} else {
Class<?> cc = elem.getClass();
JsonSerializer<Object> serializer = serializers.serializerFor(cc);
if (serializer == null) {
// To fix [JACKSON-508]
if (_elementType.hasGenericTypes()) {
serializer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_elementType, cc), provider);
} else {
serializer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicSerializers;
}
serializer.serialize(elem, jgen, provider);
}
}
} catch (Exception e) {
wrapAndThrow(provider, e, value, i);
}
}
public void serializeContentsUsing(List<?> value, JsonGenerator jgen, SerializerProvider provider,
JsonSerializer<Object> ser)
throws IOException
{
final int len = value.size();
if (len == 0) {
return;
}
final TypeSerializer typeSer = _valueTypeSerializer;
for (int i = 0; i < len; ++i) {
Object elem = value.get(i);
try {
if (elem == null) {
provider.defaultSerializeNull(jgen);
} else if (typeSer == null) {
ser.serialize(elem, jgen, provider);
} else {
ser.serializeWithType(elem, jgen, provider, typeSer);
}
} catch (Exception e) {
// [JACKSON-55] Need to add reference information
wrapAndThrow(provider, e, value, i);
}
}
}
public void serializeTypedContents(List<?> value, JsonGenerator jgen, SerializerProvider provider)
throws IOException
{
final int len = value.size();
if (len == 0) {
return;
}
int i = 0;
try {
final TypeSerializer typeSer = _valueTypeSerializer;
PropertySerializerMap serializers
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> = _dynamicSerializers;
for (; i < len; ++i) {
Object elem = value.get(i);
if (elem == null) {
provider.defaultSerializeNull(jgen);
} else {
Class<?> cc = elem.getClass();
JsonSerializer<Object> serializer = serializers.serializerFor(cc);
if (serializer == null) {
// To fix [JACKSON-508]
if (_elementType.hasGenericTypes()) {
serializer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_elementType, cc), provider);
} else {
serializer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicSerializers;
}
serializer.serializeWithType(elem, jgen, provider, typeSer);
}
}
} catch (Exception e) {
// [JACKSON-55] Need to add reference information
wrapAndThrow(provider, e, value, i);
}
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>deserFeatures;
}
/*
/**********************************************************
/* Other configuration
/**********************************************************
*/
/**
* Method for getting head of the problem handler chain. May be null,
* if no handlers have been added.
*/
public LinkedNode<DeserializationProblemHandler> getProblemHandlers() {
return _problemHandlers;
}
public final JsonNodeFactory getNodeFactory() {
return _nodeFactory;
}
/*
/**********************************************************
/* Introspection methods
/**********************************************************
*/
/**
* Method that will introspect full bean properties for the purpose
* of building a bean deserializer
*
* @param type Type of class to be introspected
*/
@SuppressWarnings("unchecked")
public <T extends BeanDescription> T introspect(JavaType type) {
return (T) getClassIntrospector().forDeserialization(this, type, this);
}
/**
* Method that will introspect subset of bean properties needed to
* construct bean instance.
*/
@SuppressWarnings("unchecked")
public <T extends BeanDescription> T introspectForCreation(JavaType type) {
return (T) getClassIntrospector().forCreation(this, type, this);
}
/**
* @since 2.0
*/
@SuppressWarnings("unchecked")
public <T extends BeanDescription> T introspectForBuilder(JavaType type) {
return (T) getClassIntrospector().forDeserializationWithBuilder(this, type, this);
}
/*
/**********************************************************
/* Support for polymorphic type handling
/**********************************************************
*/
/**
* Helper method that is needed to properly handle polymorphic referenced
* types, such as types referenced by {@link java.util.concurrent.atomic.AtomicReference},
* or various "optional" types.
*
* @since 2.4
*/
public TypeDeserializer findTypeDeserializer(JavaType baseType)
throws JsonMappingException
{
BeanDescription bean = introspectClassAnnotations(baseType.getRawClass());
AnnotatedClass ac = bean.getClassInfo();
TypeResolverBuilder<?> b = getAnnotationIntrospector().findTypeResolver(this, ac, baseType);
/* Ok: if there is no explicit type info handler, we may want to
* use a default. If so, config object knows what to use.
*/
Collection<NamedType> subtypes = null;
if (b == null) {
b = getDefaultTyper(baseType);
if (b == null) {
return null;
}
} else {
subtypes = getSubtypeResolver().collectAndResolveSubtypesByTypeId(this, ac);
}
/* 04-May-2014, tatu: When called from DeserializerFactory, additional code
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import java.lang.reflect.*;
import com.fasterxml.jackson.databind.JavaType;
/**
* Object that represents method parameters, mostly so that associated
* annotations can be processed conveniently. Note that many of accessors
* can not return meaningful values since parameters do not have stand-alone
* JDK objects associated; so access should mostly be limited to checking
* annotation values which are properly aggregated and included.
*/
public final class AnnotatedParameter
extends AnnotatedMember
{
private static final long serialVersionUID = 1L;
/**
* Member (method, constructor) that this parameter belongs to
*/
protected final AnnotatedWithParams _owner;
/**
* JDK type of the parameter, possibly contains generic type information
*/
protected final JavaType _type;
/**
* Index of the parameter within argument list
*/
protected final int _index;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public AnnotatedParameter(AnnotatedWithParams owner, JavaType type, AnnotationMap annotations,
int index)
{
super((owner == null) ? null : owner.getTypeContext(), annotations);
_owner = owner;
_type = type;
_index = index;
}
@Override
public AnnotatedParameter withAnnotations(AnnotationMap ann) {
if (ann == _annotations) {
return this;
}
return _owner.replaceParameterAnnotations(_index, ann);
}
/*
/**********************************************************
/* Annotated impl
/**********************************************************
*/
/**
* Since there is no matching JDK element, this method will
* always return null
*/
@Override
public AnnotatedElement getAnnotated() { return null; }
/**
* Returns modifiers of the constructor, as parameters do not
* have independent modifiers.
*/
@Override
public int getModifiers() { return _owner.getModifiers(); }
/**
* Parameters have no names in bytecode (unlike in source code),
* will always return empty String ("").
*/
@Override
public String getName() { return ""; }
@Override
public Class<?> getRawType() {
return _type.getRawClass();
}
@Override
public JavaType getType() {
return _typeContext.resolveType(_type);
}
/*
/**********************************************************
/* AnnotatedMember extras
/**********************************************************
*/
@Override
public Class<?> getDeclaringClass() {
return _owner.getDeclaringClass();
}
@Override
public Member getMember() {
/* This is bit tricky: since there is no JDK equivalent; can either
* return null or owner... let's do latter, for now.
*/
return _owner.
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>Result(serializer, newWith(type.getRawClass(), serializer));
}
/**
* Method called if initial lookup fails, when looking for a non-primary
* serializer (one that is not directly attached to a property).
* Will both find serializer
* and construct new map instance if warranted, and return both.
*
* @since 2.3
*
* @throws JsonMappingException
*/
public final SerializerAndMapResult findAndAddSecondarySerializer(Class<?> type,
SerializerProvider provider, BeanProperty property)
throws JsonMappingException
{
JsonSerializer<Object> serializer = provider.findValueSerializer(type, property);
return new SerializerAndMapResult(serializer, newWith(type, serializer));
}
public final SerializerAndMapResult findAndAddSecondarySerializer(JavaType type,
SerializerProvider provider, BeanProperty property)
throws JsonMappingException
{
JsonSerializer<Object> serializer = provider.findValueSerializer(type, property);
return new SerializerAndMapResult(serializer, newWith(type.getRawClass(), serializer));
}
/**
* Method called if initial lookup fails, when looking for a root value
* serializer: one that is not directly attached to a property, but needs to
* have {@link com.fasterxml.jackson.databind.jsontype.TypeSerializer} wrapped
* around it. Will both find the serializer
* and construct new map instance if warranted, and return both.
*
* @since 2.5
*
* @throws JsonMappingException
*/
public final SerializerAndMapResult findAndAddRootValueSerializer(Class<?> type,
SerializerProvider provider)
throws JsonMappingException
{
JsonSerializer<Object> serializer = provider.findTypedValueSerializer(type, false, null);
return new SerializerAndMapResult(serializer, newWith(type, serializer));
}
/**
* @since 2.5
*/
public final SerializerAndMapResult findAndAddRootValueSerializer(JavaType type,
SerializerProvider provider)
throws JsonMappingException
{
JsonSerializer<Object> serializer = provider.findTypedValueSerializer(type, false, null);
return new SerializerAndMapResult(serializer, newWith(type.getRawClass(), serializer));
}
/**
* Method called if initial lookup fails, when looking for a key
* serializer (possible attached indirectly to a property)
* Will both find serializer
* and construct new map instance if warranted, and return both.
*
* @since 2.7
*/
public final SerializerAndMapResult findAndAddKeySerializer(Class<?> type,
SerializerProvider provider, BeanProperty property)
throws JsonMappingException
{
JsonSerializer<Object> serializer = provider.findKeySerializer(type, property);
return
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> new SerializerAndMapResult(serializer, newWith(type, serializer));
}
/**
* Method that can be used to 'register' a serializer that caller has resolved
* without help of this map.
*
* @since 2.5
*/
public final SerializerAndMapResult addSerializer(Class<?> type, JsonSerializer<Object> serializer) {
return new SerializerAndMapResult(serializer, newWith(type, serializer));
}
/**
* @since 2.5
*/
public final SerializerAndMapResult addSerializer(JavaType type, JsonSerializer<Object> serializer) {
return new SerializerAndMapResult(serializer, newWith(type.getRawClass(), serializer));
}
public abstract PropertySerializerMap newWith(Class<?> type, JsonSerializer<Object> serializer);
/**
* @deprecated Since 2.5 Use {@link #emptyForProperties} instead
*/
@Deprecated
public static PropertySerializerMap emptyMap() {
return emptyForProperties();
}
/**
* @since 2.5
*/
public static PropertySerializerMap emptyForProperties() {
return Empty.FOR_PROPERTIES;
}
/**
* @since 2.5
*/
public static PropertySerializerMap emptyForRootValues() {
return Empty.FOR_ROOT_VALUES;
}
/*
/**********************************************************
/* Helper classes
/**********************************************************
*/
/**
* Value class used for returning tuple that has both serializer
* that was retrieved and new map instance
*/
public final static class SerializerAndMapResult
{
public final JsonSerializer<Object> serializer;
public final PropertySerializerMap map;
public SerializerAndMapResult(JsonSerializer<Object> serializer,
PropertySerializerMap map)
{
this.serializer = serializer;
this.map = map;
}
}
/**
* Trivial container for bundling type + serializer entries.
*/
private final static class TypeAndSerializer
{
public final Class<?> type;
public final JsonSerializer<Object> serializer;
public TypeAndSerializer(Class<?> type, JsonSerializer<Object> serializer) {
this.type = type;
this.serializer = serializer;
}
}
/*
/**********************************************************
/* Implementations
/**********************************************************
*/
/**
* Bogus instance that contains no serializers; used as the default
* map with new serializers.
*/
private final static class Empty extends PropertySerializerMap
{
// No root serializers; do not reset when full
public final static Empty FOR_PROPERTIES = new Empty(false);
// Yes, root serializers; do reset when full
public final static Empty FOR_ROOT_VALUES = new Empty(true);
protected Empty(boolean resetWhenFull) {
super(resetWhenFull);
}
@Override
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.JsonParser.NumberType;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.jsonFormatVisitors.*;
import com.fasterxml.jackson.databind.jsonschema.SchemaAware;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.PropertyFilter;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.Converter;
/**
* Base class used by all standard serializers, and can also
* be used for custom serializers (in fact, this is the recommended
* base class to use).
* Provides convenience methods for implementing {@link SchemaAware}
*/
public abstract class StdSerializer<T>
extends JsonSerializer<T>
implements JsonFormatVisitable, SchemaAware, java.io.Serializable
{
/**
* Unique key we use to store a temporary lock, to prevent infinite recursion
* when resolving content converters (see [databind#357]).
*<p>
* NOTE: may need to revisit this if nested content converters are needed; if so,
* may need to create per-call lock object. But let's start with a simpler
* solution for now.
*
* @since 2.7
*/
private final static Object CONVERTING_CONTENT_CONVERTER_LOCK = new Object();
private static final long serialVersionUID = 1L;
/**
* Nominal type supported, usually declared type of
* property for which serializer is used.
*/
protected final Class<T> _handledType;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
protected StdSerializer(Class<T> t) {
_handledType = t;
}
@SuppressWarnings("unchecked")
protected StdSerializer(JavaType type) {
_handledType = (Class<T>) type.getRawClass();
}
/**
* Alternate constructor that is (alas!) needed to work
* around kinks of generic type handling
*/
@SuppressWarnings("unchecked")
protected StdSerializer(
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> {
return _collectionType.getContentType();
}
@Override
public JsonDeserializer<Object> getContentDeserializer() {
return _valueDeserializer;
}
/*
/**********************************************************
/* JsonDeserializer API
/**********************************************************
*/
@SuppressWarnings("unchecked")
@Override
public Collection<Object> deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException
{
if (_delegateDeserializer != null) {
return (Collection<Object>) _valueInstantiator.createUsingDelegate(ctxt,
_delegateDeserializer.deserialize(p, ctxt));
}
/* [JACKSON-620]: empty String may be ok; bit tricky to check, however, since
* there is also possibility of "auto-wrapping" of single-element arrays.
* Hence we only accept empty String here.
*/
if (p.hasToken(JsonToken.VALUE_STRING)) {
String str = p.getText();
if (str.length() == 0) {
return (Collection<Object>) _valueInstantiator.createFromString(ctxt, str);
}
}
return deserialize(p, ctxt, (Collection<Object>) _valueInstantiator.createUsingDefault(ctxt));
}
@Override
public Collection<Object> deserialize(JsonParser p, DeserializationContext ctxt,
Collection<Object> result)
throws IOException
{
// Ok: must point to START_ARRAY (or equivalent)
if (!p.isExpectedStartArrayToken()) {
return handleNonArray(p, ctxt, result);
}
// [databind#631]: Assign current value, to be accessible by custom serializers
p.setCurrentValue(result);
JsonDeserializer<Object> valueDes = _valueDeserializer;
final TypeDeserializer typeDeser = _valueTypeDeserializer;
CollectionReferringAccumulator referringAccumulator =
(valueDes.getObjectIdReader() == null) ? null :
new CollectionReferringAccumulator(_collectionType.getContentType().getRawClass(), result);
JsonToken t;
while ((t = p.nextToken()) != JsonToken.END_ARRAY) {
try {
Object value;
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue(ctxt);
} else if (typeDeser == null) {
value = valueDes.deserialize(p, ctxt);
} else {
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
}
if (referringAccumulator != null) {
referringAccumulator.add(value);
} else {
result.add(value);
}
} catch (UnresolvedForwardReference reference) {
if (referringAccumulator == null) {
throw JsonMappingException
.from(p, "Unresolved forward reference
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> but no identity info", reference);
}
Referring ref = referringAccumulator.handleUnresolvedReference(reference);
reference.getRoid().appendReferring(ref);
} catch (Exception e) {
boolean wrap = (ctxt == null) || ctxt.isEnabled(DeserializationFeature.WRAP_EXCEPTIONS);
if (!wrap && e instanceof RuntimeException) {
throw (RuntimeException)e;
}
throw JsonMappingException.wrapWithPath(e, result, result.size());
}
}
return result;
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException
{
// In future could check current token... for now this should be enough:
return typeDeserializer.deserializeTypedFromArray(jp, ctxt);
}
/**
* Helper method called when current token is no START_ARRAY. Will either
* throw an exception, or try to handle value as if member of implicit
* array, depending on configuration.
*/
protected final Collection<Object> handleNonArray(JsonParser p, DeserializationContext ctxt,
Collection<Object> result)
throws IOException
{
// Implicit arrays from single values?
boolean canWrap = (_unwrapSingle == Boolean.TRUE) ||
((_unwrapSingle == null) &&
ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY));
if (!canWrap) {
throw ctxt.mappingException(_collectionType.getRawClass());
}
JsonDeserializer<Object> valueDes = _valueDeserializer;
final TypeDeserializer typeDeser = _valueTypeDeserializer;
JsonToken t = p.getCurrentToken();
Object value;
try {
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue(ctxt);
} else if (typeDeser == null) {
value = valueDes.deserialize(p, ctxt);
} else {
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
}
} catch (Exception e) {
// note: pass Object.class, not Object[].class, as we need element type for error info
throw JsonMappingException.wrapWithPath(e, Object.class, result.size());
}
result.add(value);
return result;
}
public final static class CollectionReferringAccumulator {
private final Class<?> _elementType;
private final Collection<Object> _result;
/**
* A list of {@link CollectionReferring} to maintain ordering.
*/
private List<CollectionReferring> _accumulator = new ArrayList<CollectionReferring>();
public CollectionReferringAccumulator(Class<?> elementType, Collection<Object> result) {
_elementType = elementType;
_result = result;
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> fluent factories
/********************************************************
*/
/**
* Convenience method for creating a new factory instance with additional deserializer
* provider.
*/
@Override
public final DeserializerFactory withAdditionalDeserializers(Deserializers additional) {
return withConfig(_factoryConfig.withAdditionalDeserializers(additional));
}
/**
* Convenience method for creating a new factory instance with additional
* {@link KeyDeserializers}.
*/
@Override
public final DeserializerFactory withAdditionalKeyDeserializers(KeyDeserializers additional) {
return withConfig(_factoryConfig.withAdditionalKeyDeserializers(additional));
}
/**
* Convenience method for creating a new factory instance with additional
* {@link BeanDeserializerModifier}.
*/
@Override
public final DeserializerFactory withDeserializerModifier(BeanDeserializerModifier modifier) {
return withConfig(_factoryConfig.withDeserializerModifier(modifier));
}
/**
* Convenience method for creating a new factory instance with additional
* {@link AbstractTypeResolver}.
*/
@Override
public final DeserializerFactory withAbstractTypeResolver(AbstractTypeResolver resolver) {
return withConfig(_factoryConfig.withAbstractTypeResolver(resolver));
}
/**
* Convenience method for creating a new factory instance with additional
* {@link ValueInstantiators}.
*/
@Override
public final DeserializerFactory withValueInstantiators(ValueInstantiators instantiators) {
return withConfig(_factoryConfig.withValueInstantiators(instantiators));
}
/*
/**********************************************************
/* DeserializerFactory impl (partial): type mappings
/**********************************************************
*/
@Override
public JavaType mapAbstractType(DeserializationConfig config, JavaType type) throws JsonMappingException
{
// first, general mappings
while (true) {
JavaType next = _mapAbstractType2(config, type);
if (next == null) {
return type;
}
// Should not have to worry about cycles; but better verify since they will invariably occur... :-)
// (also: guard against invalid resolution to a non-related type)
Class<?> prevCls = type.getRawClass();
Class<?> nextCls = next.getRawClass();
if ((prevCls == nextCls) || !prevCls.isAssignableFrom(nextCls)) {
throw new IllegalArgumentException("Invalid abstract type resolution from "+type+" to "+next+": latter is not a subtype of former");
}
type = next;
}
}
/**
* Method that will find abstract type mapping for specified type, doing a single
* lookup through registered abstract type resolvers; will not do recursive lookups.
*/
private JavaType _mapAbstractType2(DeserializationConfig config, JavaType type)
throws JsonMappingException
{
Class<?> currClass = type.getRawClass();
if (_factoryConfig.has
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>AbstractTypeResolvers()) {
for (AbstractTypeResolver resolver : _factoryConfig.abstractTypeResolvers()) {
JavaType concrete = resolver.findTypeMapping(config, type);
if (concrete != null && concrete.getRawClass() != currClass) {
return concrete;
}
}
}
return null;
}
/*
/**********************************************************
/* JsonDeserializerFactory impl (partial): ValueInstantiators
/**********************************************************
*/
/**
* Value instantiator is created both based on creator annotations,
* and on optional externally provided instantiators (registered through
* module interface).
*/
@Override
public ValueInstantiator findValueInstantiator(DeserializationContext ctxt,
BeanDescription beanDesc)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
ValueInstantiator instantiator = null;
// [JACKSON-633] Check @JsonValueInstantiator before anything else
AnnotatedClass ac = beanDesc.getClassInfo();
Object instDef = ctxt.getAnnotationIntrospector().findValueInstantiator(ac);
if (instDef != null) {
instantiator = _valueInstantiatorInstance(config, ac, instDef);
}
if (instantiator == null) {
/* Second: see if some of standard Jackson/JDK types might provide value
* instantiators.
*/
instantiator = _findStdValueInstantiator(config, beanDesc);
if (instantiator == null) {
instantiator = _constructDefaultValueInstantiator(ctxt, beanDesc);
}
}
// finally: anyone want to modify ValueInstantiator?
if (_factoryConfig.hasValueInstantiators()) {
for (ValueInstantiators insts : _factoryConfig.valueInstantiators()) {
instantiator = insts.findValueInstantiator(config, beanDesc, instantiator);
// let's do sanity check; easier to spot buggy handlers
if (instantiator == null) {
throw JsonMappingException.from(ctxt.getParser(),
"Broken registered ValueInstantiators (of type "+insts.getClass().getName()+"): returned null ValueInstantiator");
}
}
}
// Sanity check: does the chosen instantatior have incomplete creators?
if (instantiator.getIncompleteParameter() != null) {
final AnnotatedParameter nonAnnotatedParam = instantiator.getIncompleteParameter();
final AnnotatedWithParams ctor = nonAnnotatedParam.getOwner();
throw new IllegalArgumentException("Argument #"+nonAnnotatedParam.getIndex()+" of constructor "+ctor+" has no property name annotation; must have name when multiple-parameter constructor annotated as Creator");
}
return instantiator;
}
private ValueInstantiator _findStdValueInstantiator(DeserializationConfig config,
BeanDescription beanDesc)
throws Json
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> a 'real' one
result = new LinkedHashMap<AnnotatedWithParams,BeanPropertyDefinition[]>();
}
defs = new BeanPropertyDefinition[owner.getParameterCount()];
result.put(owner, defs);
} else {
if (defs[index] != null) {
throw new IllegalStateException("Conflict: parameter #"+index+" of "+owner
+" bound to more than one property; "+defs[index]+" vs "+propDef);
}
}
defs[index] = propDef;
}
}
return result;
}
public ValueInstantiator _valueInstantiatorInstance(DeserializationConfig config,
Annotated annotated, Object instDef)
throws JsonMappingException
{
if (instDef == null) {
return null;
}
ValueInstantiator inst;
if (instDef instanceof ValueInstantiator) {
return (ValueInstantiator) instDef;
}
if (!(instDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned key deserializer definition of type "
+instDef.getClass().getName()
+"; expected type KeyDeserializer or Class<KeyDeserializer> instead");
}
Class<?> instClass = (Class<?>)instDef;
if (ClassUtil.isBogusClass(instClass)) {
return null;
}
if (!ValueInstantiator.class.isAssignableFrom(instClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "+instClass.getName()
+"; expected Class<ValueInstantiator>");
}
HandlerInstantiator hi = config.getHandlerInstantiator();
if (hi != null) {
inst = hi.valueInstantiatorInstance(config, annotated, instClass);
if (inst != null) {
return inst;
}
}
return (ValueInstantiator) ClassUtil.createInstance(instClass,
config.canOverrideAccessModifiers());
}
protected void _addDeserializerConstructors
(DeserializationContext ctxt, BeanDescription beanDesc, VisibilityChecker<?> vchecker,
AnnotationIntrospector intr, CreatorCollector creators,
Map<AnnotatedWithParams,BeanPropertyDefinition[]> creatorParams)
throws JsonMappingException
{
// First things first: the "default constructor" (zero-arg
// constructor; whether implicit or explicit) is NOT included
// in list of constructors, so needs to be handled separately.
AnnotatedConstructor defaultCtor = beanDesc.findDefaultConstructor();
if (defaultCtor != null) {
if (!creators.hasDefaultCreator() || intr.hasCreatorAnnotation(defaultCtor)) {
creators.setDefaultCreator(defaultCtor);
}
}
// may need to keep track for [#725]
List<AnnotatedConstructor> implicitCtors = null;
for (AnnotatedConstructor ctor : beanDesc.getConstructors
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
@Deprecated // in 2.6, remove from 2.7
protected boolean _hasExplicitParamName(AnnotatedParameter param, AnnotationIntrospector intr)
{
if (param != null && intr != null) {
PropertyName n = intr.findNameForDeserialization(param);
return (n != null) && n.hasSimpleName();
}
return false;
}
/*
/**********************************************************
/* JsonDeserializerFactory impl: array deserializers
/**********************************************************
*/
@Override
public JsonDeserializer<?> createArrayDeserializer(DeserializationContext ctxt,
ArrayType type, final BeanDescription beanDesc)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
JavaType elemType = type.getContentType();
// Very first thing: is deserializer hard-coded for elements?
JsonDeserializer<Object> contentDeser = elemType.getValueHandler();
// Then optional type info: if type has been resolved, we may already know type deserializer:
TypeDeserializer elemTypeDeser = elemType.getTypeHandler();
// but if not, may still be possible to find:
if (elemTypeDeser == null) {
elemTypeDeser = findTypeDeserializer(config, elemType);
}
// 23-Nov-2010, tatu: Custom array deserializer?
JsonDeserializer<?> deser = _findCustomArrayDeserializer(type,
config, beanDesc, elemTypeDeser, contentDeser);
if (deser == null) {
if (contentDeser == null) {
Class<?> raw = elemType.getRawClass();
if (elemType.isPrimitive()) {
return PrimitiveArrayDeserializers.forType(raw);
} else if (raw == String.class) {
return StringArrayDeserializer.instance;
}
}
deser = new ObjectArrayDeserializer(type, contentDeser, elemTypeDeser);
}
// and then new with 2.2: ability to post-process it too (Issue#120)
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyArrayDeserializer(config, type, beanDesc, deser);
}
}
return deser;
}
/*
/**********************************************************
/* JsonDeserializerFactory impl: Collection(-like) deserializers
/**********************************************************
*/
@Override
public JsonDeserializer<?> createCollectionDeserializer(DeserializationContext ctxt,
CollectionType type, BeanDescription beanDesc)
throws JsonMappingException
{
JavaType contentType = type.getContentType();
// Very first thing: is deserializer hard-coded for elements?
JsonDeserializer<Object> contentDeser = contentType.getValueHandler();
final
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> DeserializationConfig config = ctxt.getConfig();
// Then optional type info: if type has been resolved, we may already know type deserializer:
TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
// but if not, may still be possible to find:
if (contentTypeDeser == null) {
contentTypeDeser = findTypeDeserializer(config, contentType);
}
// 23-Nov-2010, tatu: Custom deserializer?
JsonDeserializer<?> deser = _findCustomCollectionDeserializer(type,
config, beanDesc, contentTypeDeser, contentDeser);
if (deser == null) {
Class<?> collectionClass = type.getRawClass();
if (contentDeser == null) { // not defined by annotation
// One special type: EnumSet:
if (EnumSet.class.isAssignableFrom(collectionClass)) {
deser = new EnumSetDeserializer(contentType, null);
}
}
}
/* One twist: if we are being asked to instantiate an interface or
* abstract Collection, we need to either find something that implements
* the thing, or give up.
*
* Note that we do NOT try to guess based on secondary interfaces
* here; that would probably not work correctly since casts would
* fail later on (as the primary type is not the interface we'd
* be implementing)
*/
if (deser == null) {
if (type.isInterface() || type.isAbstract()) {
CollectionType implType = _mapAbstractCollectionType(type, config);
if (implType == null) {
// [databind#292]: Actually, may be fine, but only if polymorphich deser enabled
if (type.getTypeHandler() == null) {
throw new IllegalArgumentException("Can not find a deserializer for non-concrete Collection type "+type);
}
deser = AbstractDeserializer.constructForNonPOJO(beanDesc);
} else {
type = implType;
// But if so, also need to re-check creators...
beanDesc = config.introspectForCreation(type);
}
}
if (deser == null) {
ValueInstantiator inst = findValueInstantiator(ctxt, beanDesc);
if (!inst.canCreateUsingDefault()) {
// [databind#161]: No default constructor for ArrayBlockingQueue...
if (type.getRawClass() == ArrayBlockingQueue.class) {
return new ArrayBlockingQueueDeserializer(type, contentDeser, contentTypeDeser, inst);
}
}
// Can use more optimal deserializer if content type is String, so:
if (contentType.getRawClass() == String.class) {
// no value type deserializer because Strings are one of natural/native types:
deser
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> = new StringCollectionDeserializer(type, contentDeser, inst);
} else {
deser = new CollectionDeserializer(type, contentDeser, contentTypeDeser, inst);
}
}
}
// allow post-processing it too
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyCollectionDeserializer(config, type, beanDesc, deser);
}
}
return deser;
}
protected CollectionType _mapAbstractCollectionType(JavaType type, DeserializationConfig config)
{
Class<?> collectionClass = type.getRawClass();
collectionClass = _collectionFallbacks.get(collectionClass.getName());
if (collectionClass == null) {
return null;
}
return (CollectionType) config.constructSpecializedType(type, collectionClass);
}
// Copied almost verbatim from "createCollectionDeserializer" -- should try to share more code
@Override
public JsonDeserializer<?> createCollectionLikeDeserializer(DeserializationContext ctxt,
CollectionLikeType type, final BeanDescription beanDesc)
throws JsonMappingException
{
JavaType contentType = type.getContentType();
// Very first thing: is deserializer hard-coded for elements?
JsonDeserializer<Object> contentDeser = contentType.getValueHandler();
final DeserializationConfig config = ctxt.getConfig();
// Then optional type info (1.5): if type has been resolved, we may already know type deserializer:
TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
// but if not, may still be possible to find:
if (contentTypeDeser == null) {
contentTypeDeser = findTypeDeserializer(config, contentType);
}
JsonDeserializer<?> deser = _findCustomCollectionLikeDeserializer(type, config, beanDesc,
contentTypeDeser, contentDeser);
if (deser != null) {
// and then new with 2.2: ability to post-process it too (Issue#120)
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyCollectionLikeDeserializer(config, type, beanDesc, deser);
}
}
}
return deser;
}
/*
/**********************************************************
/* JsonDeserializerFactory impl: Map(-like) deserializers
/**********************************************************
*/
@Override
public JsonDeserializer<?> createMapDeserializer(DeserializationContext ctxt,
MapType type, BeanDescription beanDesc)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
JavaType keyType = type.getKeyType();
JavaType contentType = type.getContentType();
// First: is there annotation-specified deserializer for values?
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
@SuppressWarnings("unchecked")
JsonDeserializer<Object> contentDeser = (JsonDeserializer<Object>) contentType.getValueHandler();
// Ok: need a key deserializer (null indicates 'default' here)
KeyDeserializer keyDes = (KeyDeserializer) keyType.getValueHandler();
// Then optional type info (1.5); either attached to type, or resolved separately:
TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
// but if not, may still be possible to find:
if (contentTypeDeser == null) {
contentTypeDeser = findTypeDeserializer(config, contentType);
}
// 23-Nov-2010, tatu: Custom deserializer?
JsonDeserializer<?> deser = _findCustomMapDeserializer(type, config, beanDesc,
keyDes, contentTypeDeser, contentDeser);
if (deser == null) {
// Value handling is identical for all, but EnumMap requires special handling for keys
Class<?> mapClass = type.getRawClass();
if (EnumMap.class.isAssignableFrom(mapClass)) {
Class<?> kt = keyType.getRawClass();
if (kt == null || !kt.isEnum()) {
throw new IllegalArgumentException("Can not construct EnumMap; generic (key) type not available");
}
deser = new EnumMapDeserializer(type, null, contentDeser, contentTypeDeser);
}
// Otherwise, generic handler works ok.
/* But there is one more twist: if we are being asked to instantiate
* an interface or abstract Map, we need to either find something
* that implements the thing, or give up.
*
* Note that we do NOT try to guess based on secondary interfaces
* here; that would probably not work correctly since casts would
* fail later on (as the primary type is not the interface we'd
* be implementing)
*/
if (deser == null) {
if (type.isInterface() || type.isAbstract()) {
@SuppressWarnings("rawtypes")
Class<? extends Map> fallback = _mapFallbacks.get(mapClass.getName());
if (fallback != null) {
mapClass = fallback;
type = (MapType) config.constructSpecializedType(type, mapClass);
// But if so, also need to re-check creators...
beanDesc = config.introspectForCreation(type);
} else {
// [Issue#292]: Actually, may be fine, but only if polymorphich deser enabled
if (type.getTypeHandler() == null) {
throw new IllegalArgumentException("Can not find a deserializer for non-concrete Map type "+type);
}
deser = AbstractDeserializer.constructForNonPOJO(beanDesc);
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> /**********************************************************
/* JsonDeserializerFactory impl: other types
/**********************************************************
*/
/**
* Factory method for constructing serializers of {@link Enum} types.
*/
@Override
public JsonDeserializer<?> createEnumDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
final Class<?> enumClass = type.getRawClass();
// 23-Nov-2010, tatu: Custom deserializer?
JsonDeserializer<?> deser = _findCustomEnumDeserializer(enumClass, config, beanDesc);
if (deser == null) {
// May have @JsonCreator for static factory method:
for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) {
if (ctxt.getAnnotationIntrospector().hasCreatorAnnotation(factory)) {
int argCount = factory.getParameterCount();
if (argCount == 1) {
Class<?> returnType = factory.getRawReturnType();
// usually should be class, but may be just plain Enum<?> (for Enum.valueOf()?)
if (returnType.isAssignableFrom(enumClass)) {
deser = EnumDeserializer.deserializerForCreator(config, enumClass, factory);
break;
}
}
throw new IllegalArgumentException("Unsuitable method ("+factory+") decorated with @JsonCreator (for Enum type "
+enumClass.getName()+")");
}
}
// Need to consider @JsonValue if one found
if (deser == null) {
deser = new EnumDeserializer(constructEnumResolver(enumClass,
config, beanDesc.findJsonValueMethod()));
}
}
// and then post-process it too
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyEnumDeserializer(config, type, beanDesc, deser);
}
}
return deser;
}
@Override
public JsonDeserializer<?> createTreeDeserializer(DeserializationConfig config,
JavaType nodeType, BeanDescription beanDesc)
throws JsonMappingException
{
@SuppressWarnings("unchecked")
Class<? extends JsonNode> nodeClass = (Class<? extends JsonNode>) nodeType.getRawClass();
// 23-Nov-2010, tatu: Custom deserializer?
JsonDeserializer<?> custom = _findCustomTreeNodeDeserializer(nodeClass, config,
beanDesc);
if (custom != null) {
return custom;
}
return JsonNodeDeserializer.getDeserializer(nodeClass);
}
@Override
public JsonDeserializer<?> createReferenceDeserializer(DeserializationContext ctxt,
ReferenceType type, BeanDescription beanDesc)
throws JsonMappingException
{
JavaType contentType = type.getContentType();
// Very first thing
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>: is deserializer hard-coded for elements?
JsonDeserializer<Object> contentDeser = contentType.getValueHandler();
final DeserializationConfig config = ctxt.getConfig();
// Then optional type info: if type has been resolved, we may already know type deserializer:
TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
if (contentTypeDeser == null) { // or if not, may be able to find:
contentTypeDeser = findTypeDeserializer(config, contentType);
}
JsonDeserializer<?> deser = _findCustomReferenceDeserializer(type, config, beanDesc,
contentTypeDeser, contentDeser);
if (deser == null) {
// Just one referential type as of JDK 1.7 / Java 7: AtomicReference (Java 8 adds Optional)
if (AtomicReference.class.isAssignableFrom(type.getRawClass())) {
// 19-Apr-2016, tatu: By default we'd get something that expect to see an
// AtomicReference... but what we need is something else, so...
return new AtomicReferenceDeserializer(contentType, contentTypeDeser, contentDeser);
}
}
if (deser != null) {
// and then post-process
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyReferenceDeserializer(config, type, beanDesc, deser);
}
}
}
return deser;
}
/*
/**********************************************************
/* JsonDeserializerFactory impl (partial): type deserializers
/**********************************************************
*/
@Override
public TypeDeserializer findTypeDeserializer(DeserializationConfig config,
JavaType baseType)
throws JsonMappingException
{
BeanDescription bean = config.introspectClassAnnotations(baseType.getRawClass());
AnnotatedClass ac = bean.getClassInfo();
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findTypeResolver(config, ac, baseType);
/* Ok: if there is no explicit type info handler, we may want to
* use a default. If so, config object knows what to use.
*/
Collection<NamedType> subtypes = null;
if (b == null) {
b = config.getDefaultTyper(baseType);
if (b == null) {
return null;
}
} else {
subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByTypeId(config, ac);
}
// May need to figure out default implementation, if none found yet
// (note: check for abstract type is not 100% mandatory, more of an optimization)
if ((b.getDefaultImpl() == null) && baseType
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>.isAbstract()) {
JavaType defaultType = mapAbstractType(config, baseType);
if (defaultType != null && defaultType.getRawClass() != baseType.getRawClass()) {
b = b.defaultImpl(defaultType.getRawClass());
}
}
return b.buildTypeDeserializer(config, baseType, subtypes);
}
/**
* Overridable method called after checking all other types.
*
* @since 2.2
*/
protected JsonDeserializer<?> findOptionalStdDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
return OptionalHandlerFactory.instance.findDeserializer(type, ctxt.getConfig(), beanDesc);
}
/*
/**********************************************************
/* JsonDeserializerFactory impl (partial): key deserializers
/**********************************************************
*/
@Override
public KeyDeserializer createKeyDeserializer(DeserializationContext ctxt,
JavaType type)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
KeyDeserializer deser = null;
if (_factoryConfig.hasKeyDeserializers()) {
BeanDescription beanDesc = config.introspectClassAnnotations(type.getRawClass());
for (KeyDeserializers d : _factoryConfig.keyDeserializers()) {
deser = d.findKeyDeserializer(type, config, beanDesc);
if (deser != null) {
break;
}
}
}
// the only non-standard thing is this:
if (deser == null) {
if (type.isEnumType()) {
return _createEnumKeyDeserializer(ctxt, type);
}
deser = StdKeyDeserializers.findStringBasedKeyDeserializer(config, type);
}
// and then new with 2.2: ability to post-process it too (Issue#120)
if (deser != null) {
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyKeyDeserializer(config, type, deser);
}
}
}
return deser;
}
private KeyDeserializer _createEnumKeyDeserializer(DeserializationContext ctxt,
JavaType type)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
Class<?> enumClass = type.getRawClass();
BeanDescription beanDesc = config.introspect(type);
// 24-Sep-2015, bim: a key deserializer is the preferred thing.
KeyDeserializer des = findKeyDeserializerFromAnnotation(ctxt, beanDesc.getClassInfo());
if (des != null) {
return des;
} else {
// 24-Sep-2015, bim
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>: if no key deser, look for enum deserializer first, then a plain deser.
JsonDeserializer<?> custom = _findCustomEnumDeserializer(enumClass, config, beanDesc);
if (custom != null) {
return StdKeyDeserializers.constructDelegatingKeyDeserializer(config, type, custom);
}
JsonDeserializer<?> valueDesForKey = findDeserializerFromAnnotation(ctxt, beanDesc.getClassInfo());
if (valueDesForKey != null) {
return StdKeyDeserializers.constructDelegatingKeyDeserializer(config, type, valueDesForKey);
}
}
EnumResolver enumRes = constructEnumResolver(enumClass, config, beanDesc.findJsonValueMethod());
// May have @JsonCreator for static factory method:
final AnnotationIntrospector ai = config.getAnnotationIntrospector();
for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) {
if (ai.hasCreatorAnnotation(factory)) {
int argCount = factory.getParameterCount();
if (argCount == 1) {
Class<?> returnType = factory.getRawReturnType();
// usually should be class, but may be just plain Enum<?> (for Enum.valueOf()?)
if (returnType.isAssignableFrom(enumClass)) {
// note: mostly copied from 'EnumDeserializer.deserializerForCreator(...)'
if (factory.getRawParameterType(0) != String.class) {
throw new IllegalArgumentException("Parameter #0 type for factory method ("+factory+") not suitable, must be java.lang.String");
}
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(factory.getMember(),
ctxt.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
}
return StdKeyDeserializers.constructEnumKeyDeserializer(enumRes, factory);
}
}
throw new IllegalArgumentException("Unsuitable method ("+factory+") decorated with @JsonCreator (for Enum type "
+enumClass.getName()+")");
}
}
// [JACKSON-749] Also, need to consider @JsonValue, if one found
return StdKeyDeserializers.constructEnumKeyDeserializer(enumRes);
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
/**
* Method called to create a type information deserializer for values of
* given non-container property, if one is needed.
* If not needed (no polymorphic handling configured for property), should return null.
*<p>
* Note that this method is only called for non-container bean properties,
* and not for values in container types or root values (or container properties)
*
* @param baseType Declared base type of the value to deserializer (actual
* deserializer type will be this type or its subtype)
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>
*
* @return Type deserializer to use for given base type, if one is needed; null if not.
*/
public TypeDeserializer findPropertyTypeDeserializer(DeserializationConfig config,
JavaType baseType, AnnotatedMember annotated)
throws JsonMappingException
{
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findPropertyTypeResolver(config, annotated, baseType);
// Defaulting: if no annotations on member, check value class
if (b == null) {
return findTypeDeserializer(config, baseType);
}
// but if annotations found, may need to resolve subtypes:
Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByTypeId(
config, annotated, baseType);
return b.buildTypeDeserializer(config, baseType, subtypes);
}
/**
* Method called to find and create a type information deserializer for values of
* given container (list, array, map) property, if one is needed.
* If not needed (no polymorphic handling configured for property), should return null.
*<p>
* Note that this method is only called for container bean properties,
* and not for values in container types or root values (or non-container properties)
*
* @param containerType Type of property; must be a container type
* @param propertyEntity Field or method that contains container property
*/
public TypeDeserializer findPropertyContentTypeDeserializer(DeserializationConfig config,
JavaType containerType, AnnotatedMember propertyEntity)
throws JsonMappingException
{
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findPropertyContentTypeResolver(config, propertyEntity, containerType);
JavaType contentType = containerType.getContentType();
// Defaulting: if no annotations on member, check class
if (b == null) {
return findTypeDeserializer(config, contentType);
}
// but if annotations found, may need to resolve subtypes:
Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByTypeId(
config, propertyEntity, contentType);
return b.buildTypeDeserializer(config, contentType, subtypes);
}
/**
* Helper method called to find one of default serializers for "well-known"
* platform types: JDK-provided types, and small number of public Jackson
* API types.
*
* @since 2.2
*/
public JsonDeserializer<?> findDefaultDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
Class<?> rawType = type.getRawClass();
// Object ("untyped"), String equivalents:
if (rawType ==
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.lang.reflect.Array;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.type.ArrayType;
import com.fasterxml.jackson.databind.util.ObjectBuffer;
/**
* Basic serializer that can serialize non-primitive arrays.
*/
@JacksonStdImpl
public class ObjectArrayDeserializer
extends ContainerDeserializerBase<Object[]>
implements ContextualDeserializer
{
private static final long serialVersionUID = 1L;
// // Configuration
/**
* Full generic type of the array being deserialized
*/
protected final ArrayType _arrayType;
/**
* Flag that indicates whether the component type is Object or not.
* Used for minor optimization when constructing result.
*/
protected final boolean _untyped;
/**
* Type of contained elements: needed for constructing actual
* result array
*/
protected final Class<?> _elementClass;
/**
* Element deserializer
*/
protected JsonDeserializer<Object> _elementDeserializer;
/**
* If element instances have polymorphic type information, this
* is the type deserializer that can handle it
*/
protected final TypeDeserializer _elementTypeDeserializer;
/**
* Specific override for this instance (from proper, or global per-type overrides)
* to indicate whether single value may be taken to mean an unwrapped one-element array
* or not. If null, left to global defaults.
*
* @since 2.7
*/
protected final Boolean _unwrapSingle;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public ObjectArrayDeserializer(ArrayType arrayType,
JsonDeserializer<Object> elemDeser, TypeDeserializer elemTypeDeser)
{
super(arrayType);
_arrayType = arrayType;
_elementClass = arrayType.getContentType().getRawClass();
_untyped = (_elementClass == Object.class);
_elementDeserializer = elemDeser;
_elementTypeDeserializer = elemTypeDeser;
_unwrapSingle = null;
}
protected ObjectArrayDeserializer(ObjectArrayDeserializer base,
JsonDeserializer<Object> elemDeser, TypeDeserializer elemTypeDeser,
Boolean unwrapSingle)
{
super(base._arrayType);
_arrayType = base._arrayType;
_elementClass = base._elementClass;
_
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>untyped = base._untyped;
_elementDeserializer = elemDeser;
_elementTypeDeserializer = elemTypeDeser;
_unwrapSingle = unwrapSingle;
}
/**
* Overridable fluent-factory method used to create contextual instances
*/
public ObjectArrayDeserializer withDeserializer(TypeDeserializer elemTypeDeser,
JsonDeserializer<?> elemDeser)
{
return withResolved(elemTypeDeser, elemDeser, _unwrapSingle);
}
/**
* @since 2.7
*/
@SuppressWarnings("unchecked")
public ObjectArrayDeserializer withResolved(TypeDeserializer elemTypeDeser,
JsonDeserializer<?> elemDeser, Boolean unwrapSingle)
{
if ((unwrapSingle == _unwrapSingle)
&& (elemDeser == _elementDeserializer)
&& (elemTypeDeser == _elementTypeDeserializer)) {
return this;
}
return new ObjectArrayDeserializer(this,
(JsonDeserializer<Object>) elemDeser, elemTypeDeser, unwrapSingle);
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
BeanProperty property) throws JsonMappingException
{
JsonDeserializer<?> deser = _elementDeserializer;
Boolean unwrapSingle = findFormatFeature(ctxt, property, _arrayType.getRawClass(),
JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
// May have a content converter
deser = findConvertingContentDeserializer(ctxt, property, deser);
final JavaType vt = _arrayType.getContentType();
if (deser == null) {
deser = ctxt.findContextualValueDeserializer(vt, property);
} else { // if directly assigned, probably not yet contextual, so:
deser = ctxt.handleSecondaryContextualization(deser, property, vt);
}
TypeDeserializer elemTypeDeser = _elementTypeDeserializer;
if (elemTypeDeser != null) {
elemTypeDeser = elemTypeDeser.forProperty(property);
}
return withResolved(elemTypeDeser, deser, unwrapSingle);
}
@Override // since 2.5
public boolean isCachable() {
// Important: do NOT cache if polymorphic values, or ones with custom deserializer
return (_elementDeserializer == null) && (_elementTypeDeserializer == null);
}
/*
/**********************************************************
/* ContainerDeserializerBase API
/**********************************************************
*/
@Override
public JavaType getContentType() {
return _arrayType.getContentType();
}
@Override
public JsonDeserializer<Object> getContentDeserializer() {
return _elementDeserializer;
}
/*
/**********************************************************
/* JsonDeserializer API
/**********************************************************
*/
@Override
public Object[] deserialize(JsonParser p, DeserializationContext ctxt)
throws
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) {
String str = p.getText();
if (str.length() == 0) {
return null;
}
}
// Can we do implicit coercion to a single-element array still?
boolean canWrap = (_unwrapSingle == Boolean.TRUE) ||
((_unwrapSingle == null) &&
ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY));
if (!canWrap) {
// One exception; byte arrays are generally serialized as base64, so that should be handled
if (p.getCurrentToken() == JsonToken.VALUE_STRING
// note: not `byte[]`, but `Byte[]` -- former is primitive array
&& _elementClass == Byte.class) {
return deserializeFromBase64(p, ctxt);
}
throw ctxt.mappingException(_arrayType.getRawClass());
}
JsonToken t = p.getCurrentToken();
Object value;
if (t == JsonToken.VALUE_NULL) {
value = _elementDeserializer.getNullValue(ctxt);
} else if (_elementTypeDeserializer == null) {
value = _elementDeserializer.deserialize(p, ctxt);
} else {
value = _elementDeserializer.deserializeWithType(p, ctxt, _elementTypeDeserializer);
}
// Ok: bit tricky, since we may want T[], not just Object[]
Object[] result;
if (_untyped) {
result = new Object[1];
} else {
result = (Object[]) Array.newInstance(_elementClass, 1);
}
result[0] = value;
return result;
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>) || value.isEmpty();
}
@Override
public boolean hasSingleElement(Collection<?> value) {
Iterator<?> it = value.iterator();
if (!it.hasNext()) {
return false;
}
it.next();
return !it.hasNext();
}
/*
/**********************************************************
/* Actual serialization
/**********************************************************
*/
@Override
public final void serialize(Collection<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException
{
final int len = value.size();
if (len == 1) {
if (((_unwrapSingle == null) &&
provider.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED))
|| (_unwrapSingle == Boolean.TRUE)) {
serializeContents(value, jgen, provider);
return;
}
}
jgen.writeStartArray(len);
serializeContents(value, jgen, provider);
jgen.writeEndArray();
}
@Override
public void serializeContents(Collection<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException
{
if (_elementSerializer != null) {
serializeContentsUsing(value, jgen, provider, _elementSerializer);
return;
}
Iterator<?> it = value.iterator();
if (!it.hasNext()) {
return;
}
PropertySerializerMap serializers = _dynamicSerializers;
final TypeSerializer typeSer = _valueTypeSerializer;
int i = 0;
try {
do {
Object elem = it.next();
if (elem == null) {
provider.defaultSerializeNull(jgen);
} else {
Class<?> cc = elem.getClass();
JsonSerializer<Object> serializer = serializers.serializerFor(cc);
if (serializer == null) {
if (_elementType.hasGenericTypes()) {
serializer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_elementType, cc), provider);
} else {
serializer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicSerializers;
}
if (typeSer == null) {
serializer.serialize(elem, jgen, provider);
} else {
serializer.serializeWithType(elem, jgen, provider, typeSer);
}
}
++i;
} while (it.hasNext());
} catch (Exception e) {
wrapAndThrow(provider, e, value, i);
}
}
public void serializeContentsUsing(Collection<?> value, JsonGenerator jgen, SerializerProvider provider,
JsonSerializer<Object> ser)
throws IOException, JsonGenerationException
{
Iterator<?> it = value.iterator();
if (it.hasNext()) {
TypeSerializer typeSer = _valueTypeSerializer;
int
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>WithErrorWrapping(p, ctxt, creatorProp))) {
p.nextToken(); // to move to following FIELD_NAME/END_OBJECT
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
bean = null; // never gets here
}
if (bean == null) {
throw ctxt.instantiationException(_beanType.getRawClass(), "JSON Creator returned null");
}
// [databind#631]: Assign current value, to be accessible by custom serializers
p.setCurrentValue(bean);
// polymorphic?
if (bean.getClass() != _beanType.getRawClass()) {
return handlePolymorphic(p, ctxt, bean, unknown);
}
if (unknown != null) { // nope, just extra unknown stuff...
bean = handleUnknownProperties(ctxt, bean, unknown);
}
// or just clean?
return deserialize(p, ctxt, bean);
}
continue;
}
// Object Id property?
if (buffer.readIdProperty(propName)) {
continue;
}
// regular property? needs buffering
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) {
buffer.bufferProperty(prop, _deserializeWithErrorWrapping(p, ctxt, prop));
continue;
}
// As per [JACKSON-313], things marked as ignorable should not be
// passed to any setter
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(p, ctxt, handledType(), propName);
continue;
}
// "any property"?
if (_anySetter != null) {
try {
buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(p, ctxt));
} catch (Exception e) {
wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
}
continue;
}
// Ok then, let's collect the whole field; name and value
if (unknown == null) {
unknown = new TokenBuffer(p, ctxt);
}
unknown.writeFieldName(propName);
unknown.copyCurrentStructure(p);
}
// We hit END_OBJECT, so:
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
bean = null; // never gets here
}
if (unknown != null) {
// polymorphic?
if (bean.getClass() != _beanType.getRawClass()) {
return handlePolymorphic(null
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>, ctxt, bean, unknown);
}
// no, just some extra unknown properties
return handleUnknownProperties(ctxt, bean, unknown);
}
return bean;
}
protected final Object _deserializeWithErrorWrapping(JsonParser p,
DeserializationContext ctxt, SettableBeanProperty prop)
throws IOException
{
try {
return prop.deserialize(p, ctxt);
} catch (Exception e) {
wrapAndThrow(e, _beanType.getRawClass(), prop.getName(), ctxt);
// never gets here, unless caller declines to throw an exception
return null;
}
}
/**
* Helper method called for rare case of pointing to {@link JsonToken#VALUE_NULL}
* token. While this is most often an erroneous condition, there is one specific
* case with XML handling where polymorphic type with no properties is exposed
* as such, and should be handled same as empty Object.
*
* @since 2.7
*/
protected Object deserializeFromNull(JsonParser p, DeserializationContext ctxt)
throws IOException
{
// 17-Dec-2015, tatu: Highly specialized case, mainly to support polymorphic
// "empty" POJOs deserialized from XML, where empty XML tag synthesizes a
// `VALUE_NULL` token.
if (p.requiresCustomCodec()) { // not only XML module, but mostly it...
@SuppressWarnings("resource")
TokenBuffer tb = new TokenBuffer(p, ctxt);
tb.writeEndObject();
JsonParser p2 = tb.asParser(p);
p2.nextToken(); // to point to END_OBJECT
// note: don't have ObjectId to consider at this point, so:
Object ob = _vanillaProcessing ? vanillaDeserialize(p2, ctxt, JsonToken.END_OBJECT)
: deserializeFromObject(p2, ctxt);
p2.close();
return ob;
}
throw ctxt.mappingException(handledType());
}
/*
/**********************************************************
/* Deserializing when we have to consider an active View
/**********************************************************
*/
protected final Object deserializeWithView(JsonParser p, DeserializationContext ctxt,
Object bean, Class<?> activeView)
throws IOException
{
if (p.hasTokenId(JsonTokenId.ID_FIELD_NAME)) {
String propName = p.getCurrentName();
do {
p.nextToken();
// TODO: 06-Jan-2015, tatu: try streamlining call sequences here as well
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) {
if (!prop.visibleInView(activeView)) {
p.
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> SettableBeanProperty creatorProp = creator.findCreatorProperty(propName);
if (creatorProp != null) {
// Last creator property to set?
if (buffer.assignParameter(creatorProp, _deserializeWithErrorWrapping(p, ctxt, creatorProp))) {
t = p.nextToken(); // to move to following FIELD_NAME/END_OBJECT
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
continue; // never gets here
}
// [databind#631]: Assign current value, to be accessible by custom serializers
p.setCurrentValue(bean);
// if so, need to copy all remaining tokens into buffer
while (t == JsonToken.FIELD_NAME) {
p.nextToken(); // to skip name
tokens.copyCurrentStructure(p);
t = p.nextToken();
}
tokens.writeEndObject();
if (bean.getClass() != _beanType.getRawClass()) {
// !!! 08-Jul-2011, tatu: Could probably support; but for now
// it's too complicated, so bail out
tokens.close();
throw ctxt.mappingException("Can not create polymorphic instances with unwrapped values");
}
return _unwrappedPropertyHandler.processUnwrapped(p, ctxt, bean, tokens);
}
continue;
}
// Object Id property?
if (buffer.readIdProperty(propName)) {
continue;
}
// regular property? needs buffering
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) {
buffer.bufferProperty(prop, _deserializeWithErrorWrapping(p, ctxt, prop));
continue;
}
// Things marked as ignorable should not be passed to any setter
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(p, ctxt, handledType(), propName);
continue;
}
tokens.writeFieldName(propName);
tokens.copyCurrentStructure(p);
// "any property"?
if (_anySetter != null) {
try {
buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(p, ctxt));
} catch (Exception e) {
wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
}
}
}
// We hit END_OBJECT, so:
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
return null; // never gets here
}
return _unwrapped
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>) {
try {
_anySetter.deserializeAndSet(p, ctxt, bean, propName);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
// Unknown: let's call handler method
handleUnknownProperty(p, ctxt, bean, propName);
}
// and when we get this far, let's try finalizing the deal:
return ext.complete(p, ctxt, bean);
}
@SuppressWarnings("resource")
protected Object deserializeUsingPropertyBasedWithExternalTypeId(JsonParser p, DeserializationContext ctxt)
throws IOException
{
final ExternalTypeHandler ext = _externalTypeIdHandler.start();
final PropertyBasedCreator creator = _propertyBasedCreator;
PropertyValueBuffer buffer = creator.startBuilding(p, ctxt, _objectIdReader);
TokenBuffer tokens = new TokenBuffer(p, ctxt);
tokens.writeStartObject();
JsonToken t = p.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
String propName = p.getCurrentName();
p.nextToken(); // to point to value
// creator property?
SettableBeanProperty creatorProp = creator.findCreatorProperty(propName);
if (creatorProp != null) {
// first: let's check to see if this might be part of value with external type id:
// 11-Sep-2015, tatu: Important; do NOT pass buffer as last arg, but null,
// since it is not the bean
if (ext.handlePropertyValue(p, ctxt, propName, null)) {
;
} else {
// Last creator property to set?
if (buffer.assignParameter(creatorProp, _deserializeWithErrorWrapping(p, ctxt, creatorProp))) {
t = p.nextToken(); // to move to following FIELD_NAME/END_OBJECT
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
continue; // never gets here
}
// if so, need to copy all remaining tokens into buffer
while (t == JsonToken.FIELD_NAME) {
p.nextToken(); // to skip name
tokens.copyCurrentStructure(p);
t = p.nextToken();
}
if (bean.getClass() != _beanType.getRawClass()) {
// !!! 08-Jul-2011, tatu: Could theoretically support; but for now
// it's too complicated, so bail out
throw ctxt.mappingException("Can not create polymorphic instances with unwrapped values");
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.util;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
import com.fasterxml.jackson.databind.type.ClassKey;
/**
* Helper class for caching resolved root names.
*/
public class RootNameLookup implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
/**
* For efficient operation, let's try to minimize number of times we
* need to introspect root element name to use.
*/
protected transient LRUMap<ClassKey,PropertyName> _rootNames;
public RootNameLookup() {
_rootNames = new LRUMap<ClassKey,PropertyName>(20, 200);
}
public PropertyName findRootName(JavaType rootType, MapperConfig<?> config) {
return findRootName(rootType.getRawClass(), config);
}
public PropertyName findRootName(Class<?> rootType, MapperConfig<?> config)
{
ClassKey key = new ClassKey(rootType);
PropertyName name = _rootNames.get(key);
if (name != null) {
return name;
}
BeanDescription beanDesc = config.introspectClassAnnotations(rootType);
AnnotationIntrospector intr = config.getAnnotationIntrospector();
AnnotatedClass ac = beanDesc.getClassInfo();
name = intr.findRootName(ac);
// No answer so far? Let's just default to using simple class name
if (name == null || !name.hasSimpleName()) {
// Should we strip out enclosing class tho? For now, nope:
name = PropertyName.construct(rootType.getSimpleName());
}
_rootNames.put(key, name);
return name;
}
/*
/**********************************************************
/* Serializable overrides
/**********************************************************
*/
/**
* Need to override to reproduce cache object via constructor, instead
* of serialize/deserialize (since we do NOT want to retain cached data)
*/
protected Object readResolve() {
return new RootNameLookup();
}
}
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> factory at this point...
*/
// 05-Sep-2013, tatu: I _think_ this can be considered a primary property...
ser = provider.findPrimaryPropertySerializer(t, property);
/* 09-Dec-2010, tatu: Turns out we must add special handling for
* cases where "native" (aka "natural") type is being serialized,
* using standard serializer
*/
boolean forceTypeInformation = isNaturalTypeWithStdHandling(t.getRawClass(), ser);
return withResolved(property, ser, forceTypeInformation);
}
} else {
// 05-Sep-2013, tatu: I _think_ this can be considered a primary property...
ser = provider.handlePrimaryContextualization(ser, property);
return withResolved(property, ser, _forceTypeInformation);
}
return this;
}
/*
/**********************************************************
/* Actual serialization
/**********************************************************
*/
@Override
public void serialize(Object bean, JsonGenerator jgen, SerializerProvider prov) throws IOException
{
try {
Object value = _accessorMethod.invoke(bean);
if (value == null) {
prov.defaultSerializeNull(jgen);
return;
}
JsonSerializer<Object> ser = _valueSerializer;
if (ser == null) {
Class<?> c = value.getClass();
/* 10-Mar-2010, tatu: Ideally we would actually separate out type
* serializer from value serializer; but, alas, there's no access
* to serializer factory at this point...
*/
// let's cache it, may be needed soon again
ser = prov.findTypedValueSerializer(c, true, _property);
}
ser.serialize(value, jgen, prov);
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
Throwable t = e;
// Need to unwrap this specific type, to see infinite recursion...
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors shouldn't be wrapped (and often can't, as well)
if (t instanceof Error) {
throw (Error) t;
}
// let's try to indicate the path best we can...
throw JsonMappingException.wrapWithPath(t, bean, _accessorMethod.getName() + "()");
}
}
@Override
public void serializeWithType(Object bean, JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer0) throws IOException
{
// Regardless of other parts, first need to find value to serialize:
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>, tatu: First things first; for JSON Schema introspection,
* Enums are special, and unfortunately we will need to add special
* handling here (see https://github.com/FasterXML/jackson-module-jsonSchema/issues/57
* for details).
*/
Class<?> decl = (typeHint == null) ? null : typeHint.getRawClass();
if (decl == null) {
decl = _accessorMethod.getDeclaringClass();
}
if ((decl != null) && (decl.isEnum())) {
if (_acceptJsonFormatVisitorForEnum(visitor, typeHint, decl)) {
return;
}
}
JsonSerializer<Object> ser = _valueSerializer;
if (ser == null) {
if (typeHint == null) {
if (_property != null) {
typeHint = _property.getType();
}
if (typeHint == null) {
typeHint = visitor.getProvider().constructType(_handledType);
}
}
ser = visitor.getProvider().findTypedValueSerializer(typeHint, false, _property);
if (ser == null) {
visitor.expectAnyFormat(typeHint);
return;
}
}
ser.acceptJsonFormatVisitor(visitor, null);
}
/**
* Overridable helper method used for special case handling of schema information for
* Enums
*
* @return True if method handled callbacks; false if not; in latter case caller will
* send default callbacks
*
* @since 2.6
*/
protected boolean _acceptJsonFormatVisitorForEnum(JsonFormatVisitorWrapper visitor,
JavaType typeHint, Class<?> enumType)
throws JsonMappingException
{
// Copied from EnumSerializer#acceptJsonFormatVisitor
JsonStringFormatVisitor stringVisitor = visitor.expectStringFormat(typeHint);
if (stringVisitor != null) {
Set<String> enums = new LinkedHashSet<String>();
for (Object en : enumType.getEnumConstants()) {
try {
enums.add(String.valueOf(_accessorMethod.invoke(en)));
} catch (Exception e) {
Throwable t = e;
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
if (t instanceof Error) {
throw (Error) t;
}
throw JsonMappingException.wrapWithPath(t, en, _accessorMethod.getName() + "()");
}
}
stringVisitor.enumTypes(enums);
}
return true;
}
protected boolean isNaturalTypeWithStdHandling(Class<?> rawType, JsonSerializer<?> ser)
{
// First: do we have a natural type being handled?
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS>.getHandlerInstantiator();
}
/*
/**********************************************************
/* Configuration: type and subtype handling
/**********************************************************
*/
/**
* Method called to locate a type info handler for types that do not have
* one explicitly declared via annotations (or other configuration).
* If such default handler is configured, it is returned; otherwise
* null is returned.
*/
public final TypeResolverBuilder<?> getDefaultTyper(JavaType baseType) {
return _base.getTypeResolverBuilder();
}
public abstract SubtypeResolver getSubtypeResolver();
public final TypeFactory getTypeFactory() {
return _base.getTypeFactory();
}
/**
* Helper method that will construct {@link JavaType} for given
* raw class.
* This is a simple short-cut for:
*<pre>
* getTypeFactory().constructType(cls);
*</pre>
*/
public final JavaType constructType(Class<?> cls) {
return getTypeFactory().constructType(cls);
}
/**
* Helper method that will construct {@link JavaType} for given
* type reference
* This is a simple short-cut for:
*<pre>
* getTypeFactory().constructType(valueTypeRef);
*</pre>
*/
public final JavaType constructType(TypeReference<?> valueTypeRef) {
return getTypeFactory().constructType(valueTypeRef.getType());
}
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
return getTypeFactory().constructSpecializedType(baseType, subclass);
}
/*
/**********************************************************
/* Configuration: introspection support
/**********************************************************
*/
/**
* Accessor for getting bean description that only contains class
* annotations: useful if no getter/setter/creator information is needed.
*/
public BeanDescription introspectClassAnnotations(Class<?> cls) {
return introspectClassAnnotations(constructType(cls));
}
/**
* Accessor for getting bean description that only contains class
* annotations: useful if no getter/setter/creator information is needed.
*/
public abstract BeanDescription introspectClassAnnotations(JavaType type);
/**
* Accessor for getting bean description that only contains immediate class
* annotations: ones from the class, and its direct mix-in, if any, but
* not from super types.
*/
public BeanDescription introspectDirectClassAnnotations(Class<?> cls) {
return introspectDirectClassAnnotations(constructType(cls));
}
/**
* Accessor for getting bean description that only contains immediate class
* annotations: ones from the class, and its direct mix-in, if any, but
* not from super types.
*/
public abstract BeanDescription introspectDirectClassAnnotations(JavaType type);
/*
JacksonDatabind, 47
<FILEB>
<CHANGES>
Class<?> currRaw = type.getRawClass();
<CHANGEE>
<CHANGES>
if (serClass.isAssignableFrom(currRaw)) { // common case
<CHANGEE>
<CHANGES>
} else if (currRaw.isAssignableFrom(serClass)) { // specialization, ok as well
type = tf.constructSpecializedType(type, serClass);
} else {
throw new JsonMappingException(null,
String.format("Can not refine serialization type %s into %s; types not related",
type, serClass.getName()));
}
<CHANGEE>
<FILEE>
<FILEB>
public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException
{
JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();
// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while
// direct sub-class not yet retrofitted may only override
// those methods. With 2.8 or later we may consider removal
// of these methods
// Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a);
if (serClass != null) {
if (type.hasRawClass(serClass)) {
// 30-Nov-2015, tatu: As per [databind#1023], need to allow forcing of
// static typing this way
type = type.withStaticTyping();
} else {
<CHANGES>
<CHANGEE>
try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future?
<CHANGES>
<CHANGEE>
type = tf.constructGeneralizedType(type, serClass);
<CHANGES>
<CHANGEE>
} catch (IllegalArgumentException iae) {
throw new JsonMappingException(null,
String.format("Failed to widen type %s with annotation (value %s), from '%s': %s",
type, serClass.getName(), a.getName(), iae.getMessage()),
iae);
}
}
}
// Then further processing for container types
// First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
<FILEE>
<SCANS> 2.4 and before, was final),
// at least if they can provide access to actual size of value and use `writeStartArray()`
// variant that passes size of array to output, which is helpful with some data formats
@Override
public void serialize(T value, JsonGenerator gen, SerializerProvider provider) throws IOException
{
if (provider.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)
&& hasSingleElement(value)) {
serializeContents(value, gen, provider);
return;
}
gen.writeStartArray();
// [databind#631]: Assign current value, to be accessible by custom serializers
gen.setCurrentValue(value);
serializeContents(value, gen, provider);
gen.writeEndArray();
}
@Override
public void serializeWithType(T value, JsonGenerator gen, SerializerProvider provider,
TypeSerializer typeSer) throws IOException
{
// note: let's NOT consider [JACKSON-805] here; gets too complicated, and probably just won't work
typeSer.writeTypePrefixForArray(value, gen);
// [databind#631]: Assign current value, to be accessible by custom serializers
gen.setCurrentValue(value);
serializeContents(value, gen, provider);
typeSer.writeTypeSuffixForArray(value, gen);
}
protected abstract void serializeContents(T value, JsonGenerator gen, SerializerProvider provider)
throws IOException;
@SuppressWarnings("deprecation")
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
throws JsonMappingException
{
ObjectNode o = createSchemaNode("array", true);
JavaType contentType = _elementType;
if (contentType != null) {
JsonNode schemaNode = null;
// 15-Oct-2010, tatu: We can't serialize plain Object.class; but what should it produce here? Untyped?
if (contentType.getRawClass() != Object.class) {
JsonSerializer<Object> ser = provider.findValueSerializer(contentType, _property);
if (ser instanceof SchemaAware) {
schemaNode = ((SchemaAware) ser).getSchema(provider, null);
}
}
if (schemaNode == null) {
schemaNode = com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode();
}
o.set("items", schemaNode);
}
return o;
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
JsonSerializer<?> valueSer = _elementSerializer;
if (valueSer == null) {
valueSer = visitor.getProvider().findValueSerializer(_elementType, _property